Happy Contribupendence Day!

Did you do your five recommendations? There is still time, so get to it!

Here are my "first" five (in no particular order):

Gayle Craig - Gayle is an extremely smart and talented developer who is not afraid of facing new challenges head on. Her recent move from Java to Ruby demonstrates that she is always looking for was to expand and increase her knowledge. Instead of speaking, Gayle chooses to interact with the development community in a more personal, one on one mentoring role which I feel often does not get her the recognition that she so richly deserves.

Amanda Laucher - Amanda is one of the smartest people I have had the pleasure to know. Her ability to easily grasp and apply new, abstract and difficult concepts to mainstream development methodologies and techniques is nothing short of incredible. Her work in the .NET development community is highly appreciated and she can always be counted on to teach people something new and immediately useful.

Sarah Dutkiewicz - Sarah is an extremely smart, talented and energetic member of the .NET community. She and her colleges in Cleveland recently organized the first Day of .NET in the region with tremendous results. Her dedication to the development community is second to none. Her passion for technology is exemplified by her eagerness to learn and apply new technologies and techniques.

Jeff McWherter - Jeff has been instrumental in creating and nurturing a .NET development community in Eastern Michigan area that is an irreplaceable asset to its members. His commitment to the community was demonstrated by Jeff with the success of the Lansing Day of .NET which brought community members from as far away as Tennessee to participate and benefit from the knowledge and experience of his peers.  Jeff’s hard work and dedication to making this event so successful cannot be overstated. He is an asset to any team he is a part of.

Jeff Hunsaker - Jeff is an extremely smart, capable and talented member of the .NET community. Jeff is someone that enjoys tackling new challenges and helping others in the community overcome their own challenges. Jeff is very passionate about technology and is quick to learn new tools and techniques and find ways to leverage them in ways that make developments faster, less expensive and more successful.

So, what do I mean by my "first" five? Well, as I made my list I would think of a name that would make me think of two more names, which would make me think of two more names and so on and so on...

Currently my list is over 20 people. So, instead of trying to pare this down, I'm going to go ahead and write recommendations for ALL of them! It's going to take me probably most (all?) of the weekend, but now that I'm in the spirit of the "holiday" it seems the right thing to do.

Contribupendence Day?

What is Contribupendence Day? I mean, besides a word that apparently is not in my spell checker dictionary?

Well, according to Jeff Blankenburg, it's a day. Specifically July 3rd. More specifically, it's a day set aside for all of us in the development community to use those often overlooked features of social networking sites (like Plaxo and LinkedIn) and write something nice things about your peers.

So, on July 3rd., pick a few people who's work in the community you've appreciated in the past and write a glowing review (or just a few nice words) about them.

So, is this just another made-up holiday?

No! Well, yes. Sort of. I mean, we don't get the day off or anything, BUT we also don't have to mail out cards or buy gifts for people or anything. I mean, you can have a cook-out or something. If you want. That would be kind of cool....

Anyway, I've picked my five people. Have YOU?

Give Camp!

What is a "Give Camp?" It's an event designed to allow developers, designers, DBAs, Architects and enthusiasts to donate their time and talent by helping to developer or update applications for charities.

Many of these organizations rely on custom applications and web sites to be able to provide services, but unlike large companies they lack the funds and resources to keep these applications up to date or build them at all.

On July 11-13 you have the opportunity to help out by participating in the Ann Arbor Give Camp and using your powers for good instead of evil!

Lansing, Here I Come!

OK, short notice. Sorry about that...

For those of you in the area I will be speaking at the Lansing Day of .NET tomorrow, June 21. I will be presenting "Getting Started with WCF."

Hope to see you all there!

Lansing Day of .Net, 21 June 2008 - I'll be there!

SVCUTIL, you're my hero!

While I was putting my demos together for Cleveland Day of .NET I discovered a very frustrating, undocumented "feature" with the way the "Add Service Reference..." option works in Visual Studio 2008.

SPOILER ALERT!

My presentation is about custom behaviors, and one of my examples in an implementation of IInstanceProvider applied as an IServiceBehavior and added to my service runtime via code. I've done this a dozen times before with no issue, but this time something was amiss...

I wrote my code, fired up my application and saw the behavior "appear" to bind to my runtime. I ran my client and the call to the service worked. The only problem is that my behavior was not executed.

I had no idea what I could have done wrong. Like I said, I've done this dozens of times before with no issue. I went back and studied those old applications. Sure enough, they all still worked as expected. I started going line by line to see if there was ANYTHING I could have missed. Nothing.

Then I noticed one difference; usually I used SVCUTIL to create my proxies and add them to my client application. This time, in the interest of keeping the demo "easy" I used the "Add service reference" option from Visual Studio. In all other ways it seemed to work, but I couldn't escape the fact that it was the ONLY difference between the two solutions.

I tried a few more things around the service reference. I regenerated the reference. Nothing. I thought that maybe it was somehow calling the service before the behavior was bound (I know, kind of crazy but after 90 minutes I was started to get a little desperate). So I started the host manually, waited till I was SURE that the behavior was bound, then started the client. Nothing.

So, having exhausted all other ideas, I dropped the VS created service reference and used SVCUTIL to create a proxy object and an application configuration file. I added them to my client project, fired up the service, made my service call and... it worked!

Not being totally familiar with how VS creates the service references, I can't say for sure why it doesn't work. But, given that the behavior works when called from client that creates the channel stack (either manually via a generated proxy), I'm guessing that the service reference option is building this channel stack in a different way or somehow circumventing the aspects of the runtime on the service side.

I've never deployed an application with VS generated service references, so I'm not sure how it works in production. Or if it's even possible to deploy a WCF client in such a way. Nor have I heard of anyone else doing it.

To be honest, I prefer SVCUTIL proxies or developer written invocations of the channel stack. It gives you more control over how your client interacts with the service and if something does go horribly wrong I can debug into the stack and see what's going on.

So Mr. "Add Service Reference..." I've given you a chance, but I think I'll stick with SVCUTIL.

See you all at CDoDN!

Pimp Your WCF Runtime - Episode One

If you have ever made any effort in learning WCF, you have probably seen some variation of this:

 

static void Main(string[] args)
{
    ServiceHost host = null;
    try
    {
        host = new ServiceHost(typeof (HelloWCF), new Uri("http://localhost:8080/HelloWCF"));
        host.Description.Endpoints[0].Behaviors.Add(new MyCustomMessageFormatter("message"));
        host.Description.Behaviors.Add(new MyInstanceProvider());

        host.Opening += host_Opening;
        host.Opened += host_Opened;
        host.Faulted += host_Faulted;

        host.Open();

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

        Console.ReadKey();
    }
    finally
    {
        if (host != null)
        {
            Console.WriteLine("Closing service...");
            host.Close();
        }
    }
}

This hosting code, or some variant of it, appears in almost every book on WCF, usually in a console application. It demonstrates creating an instance of ServiceHost for a service implementation (in this case HelloWCF) with a specified URI. A couple of behaviors are added at runtime and we wire up some custom event handlers. All in all, for WCF, nothing complicated.

But what if you want to host your service in IIS? Since it comes with Windows Activation Service (WAS), IIS7 is an ideal environment to host your WCF service. So how do we get the same ability to customize our runtime in IIS?

It's actually pretty easy.

System.ServiceModel.Activation to the rescue!

IIS uses an instance of a ServiceHostFactory to create a runtime for your hosted service. If you do not provide an implementation for this class, IIS will provide you with a default implementation.

If we want to use are own hosting logic, all we have to do is create our own host class which inherits from ServiceHostFactory like so:

 

public class MyCustomHost : ServiceHostFactory
{
    public override ServiceHostBase CreateServiceHost(string constructorString, Uri[] baseAddresses)
    {
        string serviceType = 
            string.Format("{0}, {1}", constructorString,
            constructorString.Substring(0, constructorString.IndexOf(".")));

        Type t =Type.GetType(serviceType);
        
        ServiceHost host = new ServiceHost(t, baseAddresses);

        return host;
    }

    protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
    {
        ServiceHost host = new ServiceHost(serviceType, baseAddresses);

        return host;
    }
}

When we do this we need to override both implementations of CreateServiceHost, which is the method IIS calls to create the runtime for you service. For both versions we get a service type and an array of base addresses. The only real difference between the two is that the version that takes the string as the first argument is taking the service type information as a string as opposed to a .NET Type. It's an easy matter to take this string and create an instance of a Type object, in which case we can refactor the code to this:

public class MyCustomHost : ServiceHostFactory
{
    public override ServiceHostBase CreateServiceHost(string constructorString, Uri[] baseAddresses)
    {
        string serviceType = 
            string.Format("{0}, {1}", constructorString,
            constructorString.Substring(0, constructorString.IndexOf(".")));

        Type t =Type.GetType(serviceType);
        
        return this.CreateServiceHost(t, baseAddresses);
    }

    protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
    {
        ServiceHost host = new ServiceHost(serviceType, baseAddresses);

        return host;
    }
}

I think this is a better way to handle this as you are able to keep all the specialized host creation logic to the second method. For example, lets add the events from the first example:

public class MyCustomHost : ServiceHostFactory
{
    public override ServiceHostBase CreateServiceHost(string constructorString, Uri[] baseAddresses)
    {
        string serviceType = 
            string.Format("{0}, {1}", constructorString,
            constructorString.Substring(0, constructorString.IndexOf(".")));

        Type t =Type.GetType(serviceType);
        
        return this.CreateServiceHost(t, baseAddresses);
    }

    protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
    {
        ServiceHost host = new ServiceHost(serviceType, baseAddresses);

        host.Opening += host_Opening;
        host.Opened += host_Opened;
        host.Faulted += host_Faulted;
        return host;
    }

    void host_Faulted(object sender, EventArgs e)
    {
        // Some logic...
    }

    void host_Opened(object sender, EventArgs e)
    {
        // Some logic...
    }

    void host_Opening(object sender, EventArgs e)
    {
        // Some logic...
    }
}

See, nothing to it!

All that's left is hook this up to our SVC file.

Unfortunately in Visual Studio 2008 it can be a little difficult to edit the SVC file. Double clicking it brings up the code behind file and not the SVC file. To get to that file, right click the file in the Solution Explorer and select "Open with..." Select "XML Editor" from the list and you should see something that looks like this:

<%@ ServiceHost Language="C#" Debug="true" Service="CustomHostExample.Service1" CodeBehind="Service1.svc.cs" %>

To add our service host, we just add a Factory attribute that identifies our service host:

<%@ ServiceHost Language="C#" Debug="true" Service="CustomHostExample.Service1" 
    CodeBehind="Service1.svc.cs" Factory="CustomHostExample.MyCustomHost" %>

Save the SVC file and that's it! You just customized your IIS runtime environment for you WCF service.

Reliable Messaging at CODODN

thank-you

Thanks to everyone who came to either my F# talk with Amanda Laucher or my Reliable Messaging talk. If you came to both than EXTRA THANKS! 

 

As promised, here is a link to my slides and sample code from the WCF talk.

 

For those of you who missed it, I will be presenting the same talk at the Western Michigan Day of .NET in Grand Rapids on May 10th.

WM Day of .Net May 10, 2008 - I'll be there!

 

See you all there!

It's Your Fault!

In talking to people about WCF, I've noticed that a lot of people, new to WCF and not, have not realized that WCF has the ability to send rich fault information back to the client by using a Fault Contract. It's very easy. In fact, you can do it in four steps...

Step 1: Admit your faults

The first thing we need to do is determine what kind of information we want to return back to the client and create a data contract that contains that information. You may have several kinds of fault classes, and you should so that you can return specific types of information for specific faults. Kinda like why there isn't just one Exception class in .NET. Although these are data contracts, you should not use them for anything other than sending faults back to the client. Here's a sample fault class:

[DataContract]
    public class MyFault
    {
        private string _message = string.Empty;

        public MyFault(string message)
        {
            _message = message;
        }

        [DataMember]
        public string Message
        {
            get
            {
                return _message;
            }
            set
            {
                _message = value;
            }
        }
    }

Like any .NET class, you can create a fault class the inherits from another .NET class, BUT that class also needs to be a data contract and be a known type.

Step 2: Find where you may go wrong

Next, we need to let WCF know where these faults might be coming from. This is done at the operation in the service contract. You simply use a FaultContract attribute which lets WCF know what kind of possible fault class to expect:

[ServiceContract]
public interface IFaultyService
{
    [OperationContract]
    [FaultContract(typeof(MyFault))]
    void ThrowMeAnError();
}

You can specify as many faults for the operation as you like, simply add more FaultContract attributes:

[ServiceContract]
public interface IFaultyService
{
    [OperationContract]
    [FaultContract(typeof(MyFault))]
    [FaultContract(typeof(MyOtherFault))]
    [FaultContract(typeof(YetAnotherFault))]
    void ThrowMeAnError();
}

Step 3: The throw...

Throwing faults from a service is a little different than throwing them from C# or VB code. We need to enclose our fault class in a FaultException<T>, which represents a SOAP exception. This is just as easy as the other steps:

throw new FaultException<MyFault>(new MyFault("This is a fault"), "Demonstration");

The second argument, in this case "Demonstration" is the reason for the fault. And yes, "reason" is the attribute name of the fault too. This can either be a string or a FaultReason object which allows you to send more detailed information about the exception.

Step 4: ... and the catch

If you've done everything correctly, when you generate a reference to your service, in addition to the normal proxy information, you should have a class representing the data contract you created for your fault class. Catching this exception on the client side is similar to throwing it on the server side. It will come wrapped in a FaultException<T> and you will need to specify that to catch it correctly:

.
.
.
catch(FaultException<MyFault> itsMyFault)
{
    Console.WriteLine("MyFault was caught");
    Console.WriteLine(string.Format(@"Message: {0}", itsMyFault.Detail.Message));
    Console.WriteLine(string.Format(@"Reason: {0}", itsMyFault.Reason));
}
.
.
.

As you can see, getting the reason is pretty straight forward. Our message, and any other field me might have added, will be accessible as a member of the Detail child object of our fault.

That's it. See, nothing to it.

Actually, this rabbit hole does go a little deeper, but this should be enough to get you all started with capturing rich error information from your services.

Extending WCF using the IInstanceProvider and IServiceBehavior Interfaces

Recently, meaning yesterday, two of my colleagues, Kriss Scott and Matt Casto ran into an issue with one of WCF services.

To make a long story short, they needed to do some policy injection, which one or both of them will probably blog about at some point. The difficulty was getting access to the constructor of the WCF service object.

Luckily the ability to create custom behaviors in WCF makes this relatively easy.

The first step was to choose what type of functionality the behavior needed to provide. Since we are looking to effect the way the service object is created, IInstanceProvider was the obvious choice. Kriss and Matt also wanted this behavior to effect all calls to this service object, so IServiceBehavior was also to be used.

What's different?

In my last series of posts on behaviors, I created a behavior based on the IDispatchMessageInspector which, hence the name, attached to (and effected) the behavior of the message dispatcher in the WCF runtime. If you remember from my previous posts, the Dispatchers are responsible for passing messages around the runtime and controlling service runtime attributes (channel dispatcher is connected to the endpoint dispatcher, the endpoint dispatcher is connected to the operation dispatcher, the operation dispatcher is connected to the operation). This was implemented as an IEndpointBehavior which meant that it was applied to a specific endpoint. So, if a message came through the endpoint we applied the behavior to, the behavior logic would execute. If a message come into the same operation of the same service but through a different endpoint the behavior would not execute.

We "attached" our behavior (in code) thusly...

In the hosting code, before we opened the host, we added an instance of the behavior to the behavior collection for our endpoint:

host.Description.Endpoints[0].Behaviors.Add(new MyCustomMessageFormatter("message"));

This caused the runtime to call the ApplyDispatchBehavior of our custom behavior object:

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

This was the code actually responsible for adding our custom logic to the correct place in the WCF runtime, in this case the MessageInspectors collection for the EndpointDispatcher passed in from the WCF runtime. If this code wasn't here, the behavior would never have actually been implemented in our service.

But that was IDispatchMessageInspector and IEndpointBehavior.

IInstanceProvider and IServiceBehavior are different animals.

For starters, your implementation of IInstanceProvider has to be attached to the endpoint dispatchers instance provider. Unlike the message inspector, there can only be one instance provider per endpoint.

But there are a couple little "wrinkles" in this whole thing. Remember when I said that Matt and Kriss wanted to implement this at the service level and not the endpoint level? That means they need to use IServiceBehavior, not IEndpointBehavior. Well, like IEndpointBehavior, IServiceBehavior has an implementation of the ApplyDispatchBehavior:

public void ApplyDispatchBehavior(ServiceDescription serviceDescription, 
    ServiceHostBase serviceHostBase)
{

}

One thing you may notice is that unlike the endpoint behaviors version of ApplyDispatchBehavior, we get references to ServiceDescription and ServiceHostBase passed in; not ServiceEndpoint or EndpointDispatcher. But, we need to attach this behavior to an endpoint. Here's how we do it:

public void ApplyDispatchBehavior(ServiceDescription serviceDescription, 
    ServiceHostBase serviceHostBase)
{
    foreach (ChannelDispatcherBase channelDispatcherBase in serviceHostBase.ChannelDispatchers)
    {
        ChannelDispatcher channelDispatcher = channelDispatcherBase as ChannelDispatcher;
        if (channelDispatcher != null)
        {
            foreach (EndpointDispatcher endpoint in channelDispatcher.Endpoints)
            {
                endpoint.DispatchRuntime.InstanceProvider = this;
            }
        }
    }
}

Service host base gives us access to the collection of channel dispatchers, which in turn gives us a collection of endpoint dispatchers. From here it's a simple matter to iterate through each collection and attach the behavior as need.

This is the easy example. I'm just attaching the behavior to all the endpoints in all the channel dispatchers for this service. If I wanted to I could examine each endpoint and make some kind of determination about what kind of action I wanted to take on that endpoint. In this case we didn't need to.

From here it's a simple matter to add it to our runtime from code (remember to do this BEFORE you call host.Open()):

host.Description.Behaviors.Add(new MyInstanceProvider());

Or from configuration:

<service name="Sample.HelloWCF" behaviorConfiguration="MyInstanceProviderBehavior">

...

<behaviors>
    <serviceBehaviors>
        <behavior name="MyInstanceProviderBehavior">
            <MyInstanceProvider/>
        </behavior>
    </serviceBehaviors>
</behaviors>

...

<extensions>
    <behaviorExtensions>
        <add name="MyInstanceProvider"
             type="CustomBehaviorSample.InstanceProviderExtensionElement, Behavior, 
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
    </behaviorExtensions>
</extensions>

Remember, to add this behavior via configuration, you'll need a class based on BehaviorExtensionElement to do the "heavy lifting." I covered this here and a bit more here. This time around our implementation is much simpler since we aren't passing any information in at configuration and we are starting with our behavior extension element as a separate class:

class InstanceProviderExtensionElement : BehaviorExtensionElement
{
    protected override object CreateBehavior()
    {
        return new MyInstanceProvider();
    }

    public override Type BehaviorType
    {
        get { return typeof (MyInstanceProvider); }
    }
}

The last step is to implement the methods from IInstanceProvider:

public object GetInstance(InstanceContext instanceContext)
 {
     return GetInstance(instanceContext, null);
 }

 public object GetInstance(InstanceContext instanceContext, Message message)
 {
     return new HelloWCF();
 }

 public void ReleaseInstance(InstanceContext instanceContext, object instance)
 {
     return;
 }

As you see, this is relatively trivial. We have two overrides of the GetInstance method; one that takes a message (in case we want to inspect the message before deciding what kind of object to return) and one that doesn't. We also have a ReleaseInstance method to allow us to perform any additional cleanup that is needed.

So, that's all there is too it! If you have any questions feel free to leave a comment or ping me on twitter.

Later!

CONDG Q&A Follow-up and More WCF Goodness coming...

Thanks again to everybody who came to see me speak at CONDG last week.

I had several questions e-mailed to me, and thought I had answered all of them. That was until I checked my junk mail folder this morning and found five more...

So, if you sent me a question and didn't get a response you should get it in a few days.

I'll pull a few of the more interesting questions and blog them sometime next week.

In the meantime for those of you who can't get enough WCF, I'll be presenting "Reliable Messaging with WCF" at the Central Ohio Day of .NET on April 19th in Wilmington OH.

I'll also be presenting an F# talk with Amanda Laucher.

Registration is full, but I've been assured that if you show up they aren't going to make you sit outside on the curb. You just wont get one of the provided lunches. But there is a Max & Erma's in the facility, so you wont have to starve.

See you there!