Skip to content

Instantly share code, notes, and snippets.

@michaeldeongreen
Last active February 4, 2022 04:08
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 michaeldeongreen/59c01f9b7fe45636b1aa5f946ac0adfb to your computer and use it in GitHub Desktop.
Save michaeldeongreen/59c01f9b7fe45636b1aa5f946ac0adfb to your computer and use it in GitHub Desktop.
How to Implement StructureMap 4 in a WCF Service using Nested Containers
using StructureMap;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace GreenWCF.DependencyResolution
{
public class DefaultRegistry : Registry
{
public DefaultRegistry()
{
Scan(scan => {
scan.TheCallingAssembly();
scan.WithDefaultConventions();
});
}
}
}
using GreenWCF.Services;
using StructureMap;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace GreenWCF.DependencyResolution
{
public static class IoC
{
public static IContainer Initialize()
{
var registry = new Registry();
registry.IncludeRegistry<DefaultRegistry>();
var container = new Container(registry);
return container;
}
}
}
using StructureMap;
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Web;
namespace GreenWCF.DependencyResolution
{
public class StructureMapDependencyScope
{
private const string NestedContainerKey = "Nested.Container.Key";
private IContainer _currentNestedContainer;
public IContainer Container { get; private set; }
public IContainer CurrentNestedContainer
{
get
{
try
{ _currentNestedContainer= (IContainer)OperationContext.Current.IncomingMessageProperties[NestedContainerKey]; } catch (Exception) { _currentNestedContainer = null; }
return _currentNestedContainer;
}
set
{
OperationContext.Current.IncomingMessageProperties[NestedContainerKey] = value;
}
}
public StructureMapDependencyScope(IContainer container)
{
if (container == null)
throw new ArgumentNullException("container");
Container = container;
}
public void CreateNestedContainer()
{
if (CurrentNestedContainer != null)
{
return;
}
CurrentNestedContainer = Container.GetNestedContainer();
}
public void Dispose()
{
DisposeNestedContainer();
Container.Dispose();
}
public void DisposeNestedContainer()
{
if (CurrentNestedContainer != null)
{
CurrentNestedContainer.Dispose();
CurrentNestedContainer = null;
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace GreenWCF.DependencyResolution
{
public static class StructureMapWcf
{
public static StructureMapDependencyScope StructureMapDependencyScope { get; set; }
}
}
using StructureMap;
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Dispatcher;
using System.Web;
namespace GreenWCF.DependencyResolution
{
public class StructureMapInstanceProvider : IInstanceProvider
{
private readonly Type _serviceType;
public StructureMapInstanceProvider(Type serviceType)
{
_serviceType = serviceType;
}
public object GetInstance(InstanceContext instanceContext)
{
return GetInstance(instanceContext, null);
}
public object GetInstance(InstanceContext instanceContext, Message message)
{
return StructureMapWcf.StructureMapDependencyScope.CurrentNestedContainer.GetInstance(_serviceType);
}
public void ReleaseInstance(InstanceContext instanceContext, object instance)
{
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Dispatcher;
using System.Web;
namespace GreenWCF.DependencyResolution
{
public class StructureMapInspector : IDispatchMessageInspector
{
public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
{
StructureMapWcf.StructureMapDependencyScope.CreateNestedContainer();
return null;
}
public void BeforeSendReply(ref Message reply, object correlationState)
{
StructureMapWcf.StructureMapDependencyScope.DisposeNestedContainer();
}
}
}
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
using System.Web;
namespace GreenWCF.DependencyResolution
{
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);
ed.DispatchRuntime.MessageInspectors.Add(new StructureMapInspector());
}
}
}
}
public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
{
}
public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Web;
namespace GreenWCF.DependencyResolution
{
public class StructureMapServiceHost : ServiceHost
{
public StructureMapServiceHost()
{
}
public StructureMapServiceHost(Type serviceType, params Uri[] baseAddresses)
: base(serviceType, baseAddresses)
{
}
protected override void OnOpening()
{
Description.Behaviors.Add(new StructureMapServiceBehavior());
base.OnOpening();
}
}
}
using GreenWCF.Services;
using StructureMap;
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.Web;
namespace GreenWCF.DependencyResolution
{
public class StructureMapServiceHostFactory : ServiceHostFactory
{
public StructureMapServiceHostFactory()
{
IContainer container = IoC.Initialize();
StructureMapWcf.StructureMapDependencyScope = new StructureMapDependencyScope(container);
}
protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
{
return new StructureMapServiceHost(serviceType, baseAddresses);
}
}
}
<%@ ServiceHost Language="C#" Debug="true" Service="GreenWCF.GreenService" Factory="GreenWCF.DependencyResolution.StructureMapServiceHostFactory" CodeBehind="GreenService.svc.cs" %>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment