Saturday, February 23, 2008

This is not the blog you are looking for....

I have upgraded to SubText! You can find this blog now at http://jamescbender.com

For those of you still getting this via RSS fieed, you're obviously not using the feedburner feed since I'be already switched that over. To switch, point your reader at http://feeds.feedburner.com/BendersBlog

I'm not moving all the old posts (probably just the recent WCF ones), so this blog will continue to operate, but there will be no new content.

See you on the other side.

Friday, February 22, 2008

How "WCF Guy" packs

So, Brian Prince is leaving our company for Microsoft, and he's not the only one packing his stuff! Just so happens this is happening at a time when the whole company is moving to swanky new digs on the other side of the freeway.

Trust me, it's nicer than it sounds.

By way of documenting this, Brian has started a little Meme; how does <insert characteristic of you choice>guy pack.

I got tagged as the WCF guy (naturally) so I started thinking about how a WCF guy would pack. I quickly realized that I would probably want to do as much of it in configuration as possible.

Enjoy!

<?xml version="1.0" encoding="utf-8"?>
<
configuration>
<
system.PackingModel>
<
activities>
<
activity name="packing" behaviorConfiguration="packingBehavior">
<
container address="sittingOnADolly"
binding="box"
bindingConfiguration="providedMovingBoxes"
contract="IHoldsYourCrap"/>
</
activity>
</
activities>
<
bindings>
<
box>
<
binding name="providedMovingBoxes">
<
material plastic="true"/>
<
port mode="flipOpenTop"/>
<
transport mode="onADolly"/>
<
security mode="hopeNobodySeesAnythingTheyWantAndTakesIt"/>
</
binding>
</
box>
</
bindings>
<
behaviors>
<
packingBehaviors>
<
behavior name="packingBehavior">
<
breakableProtection bubbleWrapEnabled="true"/>
<
containerReturn returnContainer="true"
fineIfNotReturned="$45.00orSomething..."/>
<
bubbleWrapReturn returnBubbleWrap="true"
fineIfNotReturned="20Bucks?!"/>
</
behavior>
</
packingBehaviors>
</
behaviors>
</
system.PackingModel>
</
configuration>

I apologize for the weird layout. I'm in the process of making some "major" changes to accommodate stuff like this in the future.

Thursday, February 14, 2008

Is There Something I'm Missing Here...?

So, I guess as much as I hate to admit it, it looks like HD-DVD has lost and Blu-Ray has won. HD-DVD fought hard, but in the end Blu-Ray  had enough money to bribe "create synergies" with all but two of the major movie studios. Add to that the one-two punch from Best Buy and Netflix this week and it looks like it's all over. Frankly, I was hoping the war would just stalemate until the next big thing, probably streaming media, came in and crushed both with one blow.

So what we end up with is admittedly a technically superior format, however one that is controlled by one party: Sony.

Now that the war seems to be over, I'm seeing a lot of people posting on various on-line forums that prices of players will be coming down.

Wait.

As is my understanding Blu-Ray is controlled by Sony. Companies that want to make said hardware pay a licensing fee to Sony to use the Blu-Ray technology. No matter who you are, if you want to make a Blu-Ray disc player you have to pay Sony. This creates a situation where there is one company that controls creation and distribution of a product.

So, what incentive does Sony have to lower the prices? They are the only game in town, and could charge whatever they want. Now, I know that Sony isn't going to do something stupid like price themselves out of the market, and I don't begrudge them the right to make whatever they feel they deserve out of their creation. But seeing as they just spent a ton of money to "synergize" with all these studios, I don't see how the this is going to translate into lower prices for Blu-Ray players.

Am I wrong here? I hope I am because I can't see myself paying $300 for a Blu-Ray player. And yes, I know the Play Station 3 plays Blu-Ray movies and games. I barely have time to use the XBox I have, I don't need (or really want) another gaming console.

On the plus side, the HD-DVD fire sales have already begun. If you're a movie collector now might be the time to pick up an HD-DVD player and some movies on the cheap.

Monday, February 11, 2008

Making WCF "Behave" - Part Two

If you read my last post, you should have a pretty good idea of how Behaviors fit into the WCF stack and know that they have the ability to effect the runtime behavior (clever, huh) of your WCF host and/or client runtime by effecting the communication between dispatchers. If you missed this post, go ahead a read it now, I'll wait.

Done? Good.

In this post we are going to focus on service side behaviors (I'll cover client side behaviors soon).

Before we start slingin' code, it important to understand where the extensibility points for WCF behaviors are. On the service side there are two classes you can attach behaviors to. That are the System.ServiceModel.Dispatcher.DispatchOperation and the System.ServiceModel.Dispatcher.DispatchRuntime. Within each of these are properties that take a specific kind of interface which will be implemented by our custom behavior. Here is a quick guide to which property of which class takes which kind of interface.

DispatchRuntime

  • MessageInspectors takes IDispatchMessageInspector
  • InstanceContextProvider takes IInstanceContextProvider
  • InstanceProvider takes IInstanceProvider
  • OperationSelector takes IDispatchOperationSelector

DispatchOperation

  • ParameterInspector takes IParameterInspector
  • OperationInvoker takes IOperationInvoker
  • Formatter takes IDispatchMessageFormatter

Each property/interface pair performs a specific function in the WCF plumbing. Some are pretty obvious based on their names, others are not. I'll cover these in more detail in my upcoming seven part series "Better Know A Dispatcher Behavior."

If that doesn't make a whole lot of sense yet don't worry. As we work with behaviors just refer back to it and it will start to make sense

OK, enough theory, lets write some code!

Here we have an extremely basic WCF service:

[ServiceContract]
    public interface IHelloWCF
    {
        [OperationContract]
        string Hello(string name);
    }

    public class HelloWCF : IHelloWCF
    {
        public string Hello(string name)
        {
            return String.Format("Hello {0}", name);
        }
    }

This is hosted in a console application:

class Program
    {
        static void Main(string[] args)
        {
            using (ServiceHost host =
                new ServiceHost(typeof(HelloWCF)))
            {
                host.Open();

                Console.WriteLine("Service is available.");

                Console.ReadLine();

                host.Close();
            }
        }
    }

As you would imagine, you call this service by passing in a name, like "James" and get a warm greeting from the service ("Hello James") as you can see below:

image

We're gonna have a little fun here with a behavior based on the IDispatchMessageInspector. We are going to write a behavior to return a different message. The first step is to create a new class which implements this interface:

public object AfterReceiveRequest(ref Message request,
    IClientChannel channel,
    InstanceContext instanceContext)
{
    return null;
}

public void BeforeSendReply(ref Message reply,
    object correlationState)
{
    return;
}

As you can see, there are two methods where we need to provide implementations for. AfterRecieveRequest gets fired when a message is coming into your service. You can take this opportunity to examine and change the message if need. Today we are more concerned with the BeforeSendReply method. As the name suggests this method gives you an opportunity to change the outgoing message. The above implementation will compile and work, but it doesn't do much. Let's change that:

public void BeforeSendReply(ref Message reply,
    object correlationState)
{
    MemoryStream memoryStream = new MemoryStream();
    XmlDictionaryWriter xmlDictionary =
        XmlDictionaryWriter.CreateBinaryWriter(
        memoryStream);
    xmlDictionary.WriteStartElement("HelloResponse",
        "http://tempuri.org/");
    xmlDictionary.WriteStartElement("HelloResult",
        "http://tempuri.org/");
    xmlDictionary.WriteString
        ("Ha ha! I stole your message!");
    xmlDictionary.WriteEndElement();
    xmlDictionary.WriteEndElement();
    xmlDictionary.Flush();

    memoryStream.Position = 0;

    XmlDictionaryReaderQuotas quotas =
        new XmlDictionaryReaderQuotas();

    XmlDictionaryReader xmlReader =
        XmlDictionaryReader.CreateBinaryReader
        (memoryStream, quotas);

    Message newMessage =
        Message.CreateMessage(reply.Version,
        null, xmlReader);
    newMessage.Headers.CopyHeadersFrom(reply.Headers);
    newMessage.Properties.CopyProperties
        (reply.Properties);
    reply = newMessage;
}

The first section of code uses an XmlDictionaryWriter to create the new message body we are going to be sending back. It creates our message text, which is wrapped in a Result, which in turn is wrapped in a Response. The next section creates an XmlDictionaryReader which is used in the last section to "read" the XML we just created into a new blank WCF message. We copy the headers and properties from the original, then set the "reply" reference parameter to our new message. That's it.

Well, that's not it. He have our behavior, but right now we don't have any way to bind it to our service runtime. To do that we have to have our class implement the System.ServiceModel.Description.IEndpointBehavior. There is an interface for operation behaviors as well, but we'll worry about those at another time.

Here is how we implement the IEndpointBehavior:

class MyCustomMessageFormatter : IDispatchMessageInspector,
    IEndpointBehavior
{

    public void AddBindingParameters(
        ServiceEndpoint endpoint,
        BindingParameterCollection bindingParameters)
    {
        //Not implemented
    }

    public void ApplyClientBehavior(
        ServiceEndpoint endpoint,
        ClientRuntime clientRuntime)
    {
        //Not implemented
    }

    public void ApplyDispatchBehavior(
        ServiceEndpoint endpoint,
        EndpointDispatcher endpointDispatcher)
    {
        endpointDispatcher.DispatchRuntime.
            MessageInspectors.Add(this);
    }

    public void Validate(
        ServiceEndpoint endpoint)
    {
        //Not implemented
    }
}

Of the four methods added the one we are really only concerned with right now is the ApplyDispatchBehavior. This method is called when this endpoint behavior is applied by the runtime and it is being used here to add our message inspector (which just happens to be the same class) to the stack. You could have this endpoint behavior implemented in a separate class and have it add multiple dispatch behaviors all at once. This allows you to aggregate several dispatch behaviors into one endpoint behavior.

We're almost there now, we just need to bind our new behaior to our endpoint. First we'll do it in the hosting logic (below in bold):

class Program
{
    static void Main(string[] args)
    {
        using (ServiceHost host =
            new ServiceHost(typeof(HelloWCF)))
        {
            host.Description.Endpoints[0].
                Behaviors.Add(
                new MyCustomMessageFormatter());

            host.Open();

            Console.WriteLine("Service is available.");

            Console.ReadKey();

            host.Close();
        }
    }
}

Now, when we run the service we can see the effects of our new behavior:

image

Pretty easy! In part three I'll show how to add this behavior to the service through configuration instead of the hosting code shown above.

Thursday, February 07, 2008

THANK YOU OMAHA, GOOD NIIIIGHT!

Even though I've hemmed and hawed about it for at least six months, I have yet to purchase either Guitar Hero or Rock Band. The primary reason being that I know if I do it's just going to make me feel guilty about neglecting the six real guitars I already own.

So I was thrilled today when I saw that a company called Game Tank announced a game called "Guitar Rising" Basically, if you ever playing Rock Band or Guitar hero and thought "This would be cooler if I could use a real guitar." than this game is for you.

The way it seems to work,from the video, is that you will have the familiar "piano roll" type of interface you get with guitar hero, except instead of just having you press a specific button it shows you which string and fret combination to hit. You will be plugging your guitar into the computer somehow (sound card? USB interface? MIDI interface?) and the game will let you know how accurate you are.

To me, this is more than a game, it's a powerful teaching tool. It's more effective than sitting in a practice room with a metronome, and easier than getting a whole band together to practice whenever you want (what do you mean sleep, I wanna jam!).

Some things that I think would be great in this game:

  • Amp modeling. Presumably you are going to have to plug your guitar into this thing somehow. Line 6 has already show that PC based amp and effect modeling is possible. It would be cool to be able to not only practice the songs by your favorite band, but to do it with the same "rig" that they are using.
  • Composition mode. Basically, a type of "musical notepad" that would allow you to "dictate" notes into a song WHILE showing you the piano roll of what you have played. A lot of players try to do this with tape, but lack the "ear" to be able to figure out what they played afterward.
  • I have a small mountain of sheet music I have collected over the years. A great feature would be the ability to somehow transcribe the sheet music into songs in the game. This would make practice much more rewarding!

Suffice to say, unless there is some HUGE barrier to this game (huge price tag, need to "mutilate" one of my guitars, requirement that you wear spandex while playing) I am TOTALLY getting this!

Monday, February 04, 2008

Making WCF "Behave" - Part One

Some of the most misunderstood features of WCF are behaviors and channels. While these elements of the WCF stack offer a tremendous opportunity to customize the way WCF works, there is the perception (especially with channels) that it involves a lot of  "down to the metal" coding the requires an in-depth understand of of how communication stacks and network protocols work. While this knowledge would be helpful in any distributed computing paradigm, they are hardly required knowledge for extending WCF.

There is also a tendency to confuse behaviors and channels. While on a conceptual level these two types of objects are similar in that they effect communication  in some manner, they do so in different ways.

If you read my last post, you may remember that channels live in a stack between the binding and the transport. Therefore we can see that they impact how messages are communicated to a client and vice versa.

On the other hand, behaviors control the internal communication of the service by changing the way dispatchers function within the service host. It is fair to say that behaviors change the way the service host functions at runtime, while channels customize the way a particular endpoint communicates with a client.

So, a good follow up question is "What is a dispatcher?"

Dispatchers are basically traffic cops. The take incoming messages and route them to the appropriate service method. There are three types of dispatchers; channel, endpoint and operation.

Channel dispatchers receive messages from the channel stack. The channel dispatcher examines the address the message was sent to and sends it to the appropriate endpoint dispatcher. The endpoint dispatcher examines the action header of the message, and passes the message to the appropriate operation dispatcher. Finally, the operation dispatcher deserializes the message to get a set of parameters, and uses those parameters to call the method for the selected operation.

The use of dispatches in this manner allows us to create custom behaviors to act on endpoint operations by implementing the System.ServiceModel.Description.IEndpointBehavior interface or on an operation by implementing the System.ServiceModel.Description.IOperationBehavior interface. The separation of duties here is important as there are going to be behaviors that we wish to apply to all calls to an operation, in which case we would create an operation behavior, and others that we are only going to want to act on calls made through a specific endpoint, which would necessitate the creation of an endpoint behavior.

So, now we have a basic understanding of what behavior are, what they do, and where they fit in the WCF world. Next time we will create a basic custom behavior of our very own!