# Tuesday, May 18, 2010

One of Castle Windsor’s facilities addresses wiring up of WCF services. So far, the sparse documentation for the WCF Facility seems to indicate that you have to configure your container in a global.asax. That’s not much to my liking. First of all, it reeks of ASP.NET, and secondly, it’s not going to work if you expose WCF over protocols other than HTTP.

However, now that we know that a custom ServiceHostFactory is effectively a Singleton, a much better alternative is to derive from the WCF Facility’s DefaultServiceHost class:

public class FooServiceHostFactory : 
    DefaultServiceHostFactory
{
    public FooServiceHostFactory()
        : base(FooServiceHostFactory.CreateKernel())
    {
    }
 
    private static IKernel CreateKernel()
    {
        var container = new WindsorContainer();
 
        container.AddFacility<WcfFacility>();
 
        container.Register(Component
            .For<FooService>()
            .LifeStyle.Transient);
        container.Register(Component
            .For<IBar>()
            .ImplementedBy<Bar>());
 
        return container.Kernel;
    }
}

Although it feels a little odd to create a container and then not really use it, but only its Kernel property, this works like a charm. It correctly wires up this FooService:

public class FooService : IFooService
{
    private readonly IBar bar;
 
    public FooService(IBar bar)
    {
        if (bar == null)
        {
            throw new ArgumentNullException("bar");
        }
 
        this.bar = bar;
    }
 
    #region IFooService Members
 
    public string Foo()
    {
        return this.bar.Baz;
    }
 
    #endregion
}

However, instead of the static CreateKernel method that creates the IKernel instance, I suggest that the WCF Facility utilizes the Factory Method pattern. As the WCF Facility has not yet been released, perhaps there’s still time for that change.

In any case, the WCF Facility saves you from writing a lot of infrastructure code if you would like to wire your WCF services with Castle Windsor.

posted on Tuesday, May 18, 2010 7:27:56 AM (Romance Daylight Time, UTC+02:00)  #    Comments [6] Trackback
# Monday, May 17, 2010

For a while I’ve been wondering about the lifetime behavior of custom ServiceHostFactory classes hosted in IIS. Does IIS create an instance per request? Or a single instance to handle all requests?

I decided to find out, so I wrote a little test service. The conclusion seems to be that there is only a single instance that servers as a factory for all requests. This is very fortunate, since it gives us an excellent place to host a DI Container. The container can then manage the lifetime of all components, including Singletons that will live for the duration of the process.

If you are curious how I arrived at this conclusion, here’s the code I wrote. I started out with this custom ServiceHostFactory:

public class PocServiceHostFactory : ServiceHostFactory
{
    private static int number = 1;
 
    public PocServiceHostFactory()
    {
        Interlocked.Increment(
            ref PocServiceHostFactory.number);
    }
 
    protected override ServiceHost CreateServiceHost(
        Type serviceType, Uri[] baseAddresses)
    {
        return new PocServiceHost(
            PocServiceHostFactory.number, serviceType,
            baseAddresses);
    }
}

The idea is that every time a new instance of ServiceHostFactory is created, the static number is incremented.

The PocServiceHostFactory just forwards the number to the PocServiceHost:

public class PocServiceHost : ServiceHost
{
    public PocServiceHost(int number, Type serviceType,
        Uri[] baseAddresses)
        : base(serviceType, baseAddresses)
    {
        foreach (var cd in 
            this.ImplementedContracts.Values)
        {
            cd.Behaviors.Add(
                new NumberServiceInstanceProvider(
                    number));
        }
    }
}

The PocServiceHost just forwards the number to the NumberServiceInstanceProvider:

public class NumberServiceInstanceProvider : 
    IInstanceProvider, IContractBehavior
{
    private readonly int number;
 
    public NumberServiceInstanceProvider(int number)
    {
        this.number = number;
    }
 
    #region IInstanceProvider Members
 
    public object GetInstance(
        InstanceContext instanceContext,
        Message message)
    {
        return this.GetInstance(instanceContext);
    }
 
    public object GetInstance(
        InstanceContext instanceContext)
    {
        return new NumberService(this.number);
    }
 
    public void ReleaseInstance(
        InstanceContext instanceContext,
        object instance)
    {
    }
 
    #endregion
 
    #region IContractBehavior Members
 
    public void AddBindingParameters(
        ContractDescription contractDescription,
        ServiceEndpoint endpoint,
        BindingParameterCollection bindingParameters)
    {
    }
 
    public void ApplyClientBehavior(
        ContractDescription contractDescription,
        ServiceEndpoint endpoint,
        ClientRuntime clientRuntime)
    {
    }
 
    public void ApplyDispatchBehavior(
        ContractDescription contractDescription,
        ServiceEndpoint endpoint,
        DispatchRuntime dispatchRuntime)
    {
        dispatchRuntime.InstanceProvider = this;
    }
 
    public void Validate(
        ContractDescription contractDescription,
        ServiceEndpoint endpoint)
    {
    }
 
    #endregion
}

The relevant part of NumberServiceInstanceProvider is the GetInstanceMethod that simply forwards the number to the NumberService:

public class NumberService : INumberService
{
    private readonly int number;
 
    public NumberService(int number)
    {
        this.number = number;
    }
 
    #region INumberService Members
 
    public int GetNumber()
    {
        return this.number;
    }
 
    #endregion
}

As you can see, NumberService simply returns the injected number.

The experiment is now to host NumberService in IIS using PocServiceHostFactory. If there is only one ServiceHostFactory per application process, we would expect that the same number (2) is returned every time we invoke the GetNumber operation. If, on the other hand, a new instance of ServiceHostFactory is created per request, we would expect the number to increase for every request.

To test this I spun up a few instances of WcfTestClient.exe and invoked the operation. It consistently returns 2 across multiple clients and multiple requests. This supports the hypothesis that there is only one ServiceHostFactory per service process.

posted on Monday, May 17, 2010 7:42:33 AM (Romance Daylight Time, UTC+02:00)  #    Comments [1] Trackback
# Saturday, October 24, 2009

Daniel Frost has published a podcast where he discusses WCF with me. It's about half an hour and in Danish. Hear it here.

posted on Saturday, October 24, 2009 3:52:18 AM (Romance Daylight Time, UTC+02:00)  #    Comments [0] Trackback
# Monday, June 22, 2009

About a year ago, one of my readers asked me about how to make custom tokens work over TPC in WCF. Here's the question again:

"i'm trying to implement the CustomToken over tcp. The original used the SymmetricSecurityBindingElement and the transport http, this works fine, but when i change URI's and and the transport, it gives an error saying:

"Binding 'CustomBinding' doesn't support creating any channel types. This often indicates that the BindingElements in a CustomBinding have been stacked incorrectly or in the wrong order. A Transport is required at the bottom of the stack. The recommended order for BindingElements is: TransactionFlow, ReliableSession, Security, CompositeDuplex, OneWay, StreamSecurity, MessageEncoding, Transport."

As it turns out, this seems to be a general issue with more transports than just TCP – at least, I've seen the exact same behavior for the Named Pipes transport.

When I originally received the question, it seemed that no-one knew the answer, and neither did I. Now, about a year later, I've managed to find a solution, and it's really simple.

If you build up your CustomBinding in code, all you need to do is set the TransferMode property to Streamed:

var pipeTransport = new NamedPipeTransportBindingElement();
pipeTransport.TransferMode = TransferMode.Streamed;

In this example, I'm setting the property on a Named Pipe transport, but you can do exactly the same with a TCP transport.

Although I wasn't able to find any documentation to that effect, experimentation seems to indicate that you can also set the property in a .config file (at least, it works on my computer):

<namedPipeTransport transferMode="Streamed" />

I will not claim that I fully understand this fix/workaround, or that it applies in every situation, but I hope that it might prove helpful to some of my readers some day.

posted on Monday, June 22, 2009 9:48:42 PM (Romance Daylight Time, UTC+02:00)  #    Comments [0] Trackback