2009-12-15 17 views
6

Acabo de ingresar al MEF y me he encontrado con un problema que no puedo resolver. Tengo un servicio de Windows que está leyendo en mi DLL (a través de MEF) y cada DLL es un host de servicio WCF. Cuando ejecuto mi servicio de Windows y leo en las DLL todo funciona bien, excepto que cada vez que una de las DLL de WCF obtiene alguna "actividad", entonces reinstalan y luego procesan los datos que ingresan. Los necesito para crear una instancia al principio. es posible?MEF + WCF ¿Servicio Host?

Respuesta

4

WCF servicios por defecto a una por ejemplo el modo de llamada. Esto significa que una instancia nueva de su servicio WCF se instancia para cada invocación de método entrante. Parece que lo que quieres es un modo de instancia singleton, pero realmente quieres evitar esto si la escalabilidad es un problema.

La forma en que he salido de esto es utilizar el modo de instancia por llamada, pero tengo un almacén de datos estático detrás de las escenas al que sincronizo el acceso. Esto al menos permite a los clientes conectarse, incluso si tienen que bloquear momentáneamente mientras el almacén de datos está en uso una vez que se establece la conexión.

consulte la ayuda de MSDN en System.ServiceModel.InstanceContextMode para más detalles.

4

que puede manejar esto mediante la aplicación de un IServiceBehavior y un IInstanceProvider, registrando mi implmentation de IServiceBehavior en OnStart, y tener IInstanceProvider gestionar duración del objeto para usted. En particular, puede usar un contenedor de inversión de control que sirva la misma instancia de su tipo de servicio en cada solicitud (es decir, comportamiento de tipo singleton sin ser un singleton).

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) { }  
} 
+0

Supongo que podría darme una pequeña muestra o tal vez entrar en más detalles. De ninguna manera soy una exportación en MEF o WCF. – Travyguy9

+0

Agregué una implementación barebones de lo que estoy hablando. La clave es la inversión del contenedor de control que gestiona la duración del objeto. – jason

+0

¿Qué conjunto está ubicado en IIocContainer? – Travyguy9