2009-12-15 17 views
6

Sto appena entrando in MEF e mi sono imbattuto in un problema che non riesco a risolvere. Ho un servizio di Windows che sta leggendo nelle mie DLL (tramite MEF) e ogni DLL è un host di servizio WCF. Quando eseguo il mio servizio Windows e leggo le DLL, tutto gira bene, eccetto che ogni volta che una delle DLL WCF ottiene una qualsiasi "attività", allora reinventa e quindi elabora i dati in arrivo. Ho bisogno di istanziarli una volta all'inizio. È possibile?Host di servizi MEF + WCF?

risposta

4

WCF servizi di default ad un per chiamata modalità istanza. Ciò significa che una nuova istanza del servizio WCF viene creata un'istanza per ogni chiamata di metodo in entrata. Sembra che quello che stai cercando sia una modalità di istanza singleton , ma vuoi davvero evitare questo se la scissura è un problema.

Il modo in cui ho ottenuto intorno a questo è quello di utilizzare il per chiamata modalità esempio, ma hanno un archivio di dati statici dietro le quinte che ho sincronizzare l'accesso a. Ciò consente almeno ai client di connettersi, anche se devono bloccarsi momentaneamente mentre l'archivio dati è in uso una volta stabilita la connessione.

Per ulteriori dettagli, fare riferimento alla guida MSDN su System.ServiceModel.InstanceContextMode.

4

È possibile gestire questo implementando un IServiceBehavior e un IInstanceProvider, registrando il mio implmentation di IServiceBehavior in OnStart, e avendo IInstanceProvider gestire durata degli oggetti per voi. In particolare, è possibile utilizzare un'inversione del contenitore di controllo che serve la stessa istanza del tipo di servizio su ogni richiesta (ad esempio, un comportamento simile al singleton senza essere 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

Immagino che potresti darmi un piccolo campione o magari andare più nel dettaglio. Non sono affatto un'esportazione in MEF o WCF. – Travyguy9

+0

Ho aggiunto un'implementazione barebone di ciò di cui sto parlando. La chiave è l'inversione del contenitore di controllo che gestisce la durata dell'oggetto. – jason

+0

Quale assembly è situato su IIocContainer? – Travyguy9

Problemi correlati