MEF + WCF Service Host?

I just get into MEF and I have a problem that I cannot solve. I have a Windows service that reads my DLLs (via MEF), and each DLL is a WCF Service Host. When I start my Windows service and read in the DLL, everything works fine, except that whenever one of the WCF DLLs gets any β€œactivity”, they restore and process the incoming data. I need them to just instantiate once at the beginning. Is it possible?

+6
c # wcf mef
source share
2 answers

The default WCF service is used for instance mode of each call. This means that a new instance of your WCF service is created for every incoming method call. This is similar to what you want - this is single-user instance mode, but you really want to avoid this if the scaling issue is a problem.

The way I got around this is to use the instance mode of each call, but I have a static data store behind the scenes to which I am synchronizing access. This at least allows clients to connect, even if they have to instantly block while the data store is being used after the connection is established.

See the MSDN help on System.ServiceModel.InstanceContextMode for details.

+4
source share

You can handle this by implementing IServiceBehavior and IInstanceProvider , registering my IServiceBehavior implementation on OnStart and having IInstanceProvider manage the object's lifetime for you. In particular, you can use the inverse of the control container, which serves the same instance of your type of service for each request (i.e., single-user behavior without a single).

 public partial class MyServiceHost : ServiceBase { // details elided protected override void OnStart(string[] args) { this.Host = new ServiceHost(typeof(MySerivce)); this.Host.Description.Behaviors.Add(new MyServiceBehavior()); this.Host.Open(); } } public class MyServiceBehavior : IServiceBehavior { public void AddBindingParameters( ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters ) { } public void ApplyDispatchBehavior( ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) { IIoCContainer container = new IocContainer(); foreach (var cdBase in serviceHostBase.ChannelDispatchers) { ChannelDispatcher cd = cdBase as ChannelDispatcher; if (cd != null) { foreach (EndpointDispatcher ed in cd.Endpoints) { ed.DispatchRuntime.InstanceProvider = new MyInstanceProvider( container, serviceDescription.ServiceType ); } } } } public void Validate( ServiceDescription serviceDescription, ServiceHostBase serviceHostBase ) { } } public class MyInstanceProvider : IInstanceProvider { readonly IIocContainer _container; readonly Type _serviceType; public InstanceProvider(IIoCContainer container, Type serviceType) { _container = container; _serviceType = serviceType; } public object GetInstance(InstanceContext instanceContext, Message message) { return _container.Resolve(_serviceType); } public object GetInstance(InstanceContext instanceContext) { return GetInstance(instanceContext, null); } public void ReleaseInstance(InstanceContext instanceContext, object instance) { } } 
+4
source share

All Articles