2017-07-26 85 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上,我无法创建这种行为