2009-12-15 196 views
6

我剛剛進入MEF,遇到了一個我無法解決的問題。我有一個Windows服務正在讀取我的DLL(通過MEF),每個DLL都是一個WCF服務主機。當我運行Windows服務並讀取DLL時,一切運行良好,除非每當WCF DLL中的一個獲得任何「活動」時,它們將重新實例化並處理數據。我需要它們在開始時僅實例化一次。這可能嗎?MEF + WCF服務主機?

回答

4

WCF服務默認爲每個呼叫實例模式。這意味着爲每個傳入方法調用實例化WCF服務的新實例。這聽起來像你想要的是一個單身人士實例模式,但如果scability是一個問題,你真的想避免這種情況。

我這樣做的方式是每次調用實例模式使用,但在同步訪問的場景後面有一個靜態數據存儲區。這至少允許客戶端進行連接,即使連接建立後數據存儲區正在使用時它們必須暫時阻止。

有關更多詳細信息,請參閱System.ServiceModel.InstanceContextMode上的MSDN幫助。

4

您可以通過實施IServiceBehaviorIInstanceProvider,在OnStart註冊我的IServiceBehavior implmentation,並具有IInstanceProvider管理對象的生命週期爲您處理這個問題。特別是,您可以使用控制容器的反轉,該容器在每個請求上提供相同的服務類型實例(即,不需要單個實例就可以實現類似單身的行爲)。

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

我想你可以給我一個小樣本,或者可以進入更多的細節。我絕不是在MEF或WCF中出口。 – Travyguy9 2009-12-15 16:42:34

+0

我添加了一個我正在談論的準系統實現。關鍵是管理對象生命期的控制容器的反轉。 – jason 2009-12-15 17:04:00

+0

IIocContainer位於哪個組件? – Travyguy9 2009-12-15 18:24:58