Skip to content

Instantly share code, notes, and snippets.

@cybermaxs
Last active April 21, 2016 15:55
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cybermaxs/17d620d44a810c5bccce232178745048 to your computer and use it in GitHub Desktop.
Save cybermaxs/17d620d44a810c5bccce232178745048 to your computer and use it in GitHub Desktop.
an attempt to StructureMap4 and nested containers in WCF
using StructureMap;
using System;
using System.ServiceModel;
namespace MyWcfService.Classes
{
public class CustomServiceHost : ServiceHost
{
public CustomServiceHost(IContainer container, Type serviceType, params Uri[] baseAddresses)
: base(serviceType, baseAddresses)
{
if (container == null)
throw new ArgumentNullException("container");
Description.Behaviors.Add(new StructureMapServiceBehavior(container));
}
}
}
using MyWcfService.Registries;
using StructureMap;
using System;
using System.ServiceModel;
using System.ServiceModel.Activation;
namespace MyWcfService.Classes
{
public class CustomServiceHostFactory : ServiceHostFactory
{
private readonly IContainer container; //the root container
public CustomServiceHostFactory()
{
// configure your registry here
container = new Container(r => r.AddRegistry<MyRegistry>());
}
protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
{
return new CustomServiceHost(container, serviceType, baseAddresses);
}
}
}
using MyWcfService.Services;
namespace MyWcfService
{
public class Service1 : IService1
{
public Service1(IFoo fooService, IBar barService)
{
}
/// code here
}
}
using StructureMap;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Dispatcher;
namespace MyWcfService.Classes
{
public class StructureMapDispatchMessageInspector : IDispatchMessageInspector
{
public const string ContainerKey = "container";
private readonly IContainer root;
public StructureMapDispatchMessageInspector(IContainer root)
{
this.root = root;
}
public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
{
var container = root.GetNestedContainer();
OperationContext.Current.IncomingMessageProperties[ContainerKey] = container;
return container;
}
public void BeforeSendReply(ref Message reply, object correlationState)
{
var container = (IContainer)correlationState;
container.Dispose();
}
}
}
using StructureMap;
using System;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Dispatcher;
namespace MyWcfService.Classes
{
public class StructureMapInstanceProvider : IInstanceProvider
{
private readonly Type serviceType;
public StructureMapInstanceProvider(Type serviceType)
{
this.serviceType = serviceType;
}
#region IInstanceProvider
public object GetInstance(InstanceContext instanceContext, Message message)
{
return GetInstance(instanceContext);
}
public object GetInstance(InstanceContext instanceContext)
{
var container = (IContainer)OperationContext.Current.IncomingMessageProperties[StructureMapDispatchMessageInspector.ContainerKey];
return container.GetInstance(serviceType);
}
public void ReleaseInstance(InstanceContext instanceContext, object instance)
{
// Allow the lifetime management behavior of StructureMap to release dependencies
}
#endregion
}
}
using StructureMap;
using System;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
using System.Collections.ObjectModel;
using System.ServiceModel;
namespace MyWcfService.Classes
{
public class StructureMapServiceBehavior : IServiceBehavior
{
private readonly IContainer container;
public StructureMapServiceBehavior(IContainer container)
{
if (container == null)
throw new ArgumentNullException("container");
this.container = container;
}
public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
{
}
public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
foreach (ChannelDispatcherBase cdb in serviceHostBase.ChannelDispatchers)
{
var cd = cdb as ChannelDispatcher;
if (cd != null)
{
foreach (EndpointDispatcher ed in cd.Endpoints)
{
ed.DispatchRuntime.InstanceProvider = new StructureMapInstanceProvider(serviceDescription.ServiceType);
ed.DispatchRuntime.MessageInspectors.Add(new StructureMapDispatchMessageInspector(container));
}
}
}
}
public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment