2017-07-26 84 views
1

我正在嘗試在WCF服務中注入一些業務服務。我讀這真的interessting帖子:How do I pass values to the constructor on my wcf service?如何在WCF服務中注入依賴關係

而且我也做了以下內容:

自定義的ServiceHost

public class UnityServiceHost : ServiceHost 
    { 
     public UnityServiceHost(IUnityContainer container, Type serviceType, params Uri[] baseAddresses) 
      : base(serviceType, baseAddresses) 
     { 
      if (container == null) 
      { 
       throw new ArgumentNullException(nameof(container)); 
      } 

      foreach (ContractDescription contractDescription in ImplementedContracts.Values) 
      { 
       contractDescription.Behaviors.Add(new UnityInstanceProvider(serviceType, container)); 
      } 
     } 
    } 

自定義實例提供

public class UnityInstanceProvider : IInstanceProvider, IContractBehavior 
{ 
    private readonly Type m_serviceType; 
    private readonly IUnityContainer m_container; 

    public UnityInstanceProvider(Type serviceType, IUnityContainer container) 
    { 
     m_serviceType = serviceType; 
     m_container = container; 
    } 
    public object GetInstance(InstanceContext instanceContext, Message message) 
    { 
     return GetInstance(instanceContext); 
    } 
    public object GetInstance(InstanceContext instanceContext) 
    { 
     return m_container.Resolve(m_serviceType); 
    } 
    public void ReleaseInstance(InstanceContext instanceContext, object instance) 
    { 
     (instance as IDisposable)?.Dispose(); 
    } 
    public void AddBindingParameters(ContractDescription contractDescription, ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)  {  } 

    public void ApplyClientBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, ClientRuntime clientRuntime)  {  } 


    public void ApplyDispatchBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, DispatchRuntime dispatchRuntime) 
    { 
     dispatchRuntime.InstanceProvider = this; 
    } 

    public void Validate(ContractDescription contractDescription, ServiceEndpoint endpoint)  {  } 
} 

服務行爲我看起來像這樣:

[ServiceBehavior] 
public class MyService : IMyService 
{ 
    public ServerInformationService(ISomeDependency coreManager) 
    { 
     //... 
    } 
} 

但我不進入GetInstance,當我運行代碼,我得到這個:

提供,因爲它 沒有無法加載爲服務的服務類型有一個默認(無參數)的構造函數。要修復 問題,請向該類型添加默認構造函數,或將類型爲 的實例傳遞給主機。

我做錯了什麼?它看起來像我的實例提供商甚至沒有使用

+0

這表明您正在嘗試注入的依賴項應該有一個無參數構造函數 – ArunGeorge

+0

@A runGeorge我不這麼認爲,它的事件並不停止在'return m_container.Resolve(m_serviceType);'斷點上,我可以在WPF之外尋求與依賴關係相同的服務。 – J4N

+0

您的服務是否託管在IIS中?你在使用'UnityServiceHost'類嗎? –

回答

0

我終於找到了解決方案。我正在將我的InstanceProvider應用於聯繫人而不是服務。

這是我最後的(工作)解決方案:

public class UnityServiceHost : ServiceHost 
{ 
    public UnityServiceHost(IUnityContainer container, Type serviceType, params Uri[] baseAddresses) 
     : base(serviceType, baseAddresses) 
    { 
     if (container == null) 
     { 
      throw new ArgumentNullException(nameof(container)); 
     } 
     Description.Behaviors.Add(new UnityInstanceProvider(serviceType, container)); 
    } 
} 

而且行爲+實例提供:

public class UnityInstanceProvider : IInstanceProvider, IServiceBehavior 
{ 
    private readonly Type m_serviceType; 
    private readonly IUnityContainer m_container; 

    public UnityInstanceProvider(Type serviceType, IUnityContainer container) 
    { 
     m_serviceType = serviceType; 
     m_container = container; 
    } 

    public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) 
    { 
    } 

    public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters) 
    { 
    } 

    public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) 
    { 
     foreach (ChannelDispatcherBase channelDispatcherBase in serviceHostBase.ChannelDispatchers) 
     { 
      ChannelDispatcher cd = (ChannelDispatcher)channelDispatcherBase; 
      foreach (EndpointDispatcher ed in cd.Endpoints) 
      { 
       if (!ed.IsSystemEndpoint) 
       { 
        ed.DispatchRuntime.InstanceProvider = this; 
       } 
      } 
     } 
    } 

    public object GetInstance(InstanceContext instanceContext) 
    { 
     return m_container.Resolve(m_serviceType); 
    } 

    public object GetInstance(InstanceContext instanceContext, Message message) 
    { 
     return GetInstance(instanceContext); 
    } 

    public void ReleaseInstance(InstanceContext instanceContext, object instance) 
    { 
     (instance as IDisposable)?.Dispose(); 
    } 
} 

它的工作原理,因爲我自託管的服務(new UnityServiceHost(...) ....,如果在IIS上,我無法創建這種行爲