I’ve recently had the need to link WCF and StructureMap (I don’t do “no IoC”). Jimmy Bogard has a nifty blog post with the requisite code to get this all working. The key class looks like this:
public class StructureMapServiceBehavior : IServiceBehavior
{
public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
foreach (ChannelDispatcherBase cdb in serviceHostBase.ChannelDispatchers)
{
ChannelDispatcher cd = cdb as ChannelDispatcher;
if (cd != null)
{
foreach (EndpointDispatcher ed in cd.Endpoints)
{
ed.DispatchRuntime.InstanceProvider =
new StructureMapInstanceProvider(serviceDescription.ServiceType);
}
}
}
}
public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
{
}
public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
}
}
This works, but it’s got nested loops and I’m mildly completely obsessed about this kind of thing. I’m putting this into my code which means that it’s now my responsibility. If I’m going to maintain it then it needs to fit with the rest of my code. Hence my new version:
public class StructureMapServiceBehaviour : IServiceBehavior
{
public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
serviceHostBase.ChannelDispatchers
.OfType<ChannelDispatcher>()
.SelectMany(dispatcher => dispatcher.Endpoints)
.Apply(endpointDispatcher => endpointDispatcher.DispatchRuntime.InstanceProvider
= new StructureMapInstanceProvider(serviceDescription.ServiceType));
}
public void AddBindingParameters(ServiceDescription serviceDescription,
ServiceHostBase serviceHostBase,
Collection<ServiceEndpoint> endpoints,
BindingParameterCollection bindingParameters)
{
}
public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
}
}
The addition of a little LINQ magic takes care of the nested loops and produces something I find cleaner and easier to maintain. It took little time to do and it gave me a better understanding of what this class done. I call that a win all round.
The Apply method is my variant of a ForEach that applies the supplied action delegate to every element of an IEnumerable<T>. I’m aware some people have objections to this but I argue the simplicity gain from the above is worth any notional degradation in purity.