我正在尝试在WCF服务中注入一些业务服务。我读了这篇非常有意思的帖子:How do I pass values to the constructor on my wcf service?
我做了以下事情:
自定义ServiceHost
autocmd WinEnter,BufWinEnter,FileType,ColorScheme,SessionLoadPost * let w:left = StatuslineComponents('left')
let &statusline = "%{w:left}%=%{StatuslineComponents('right')}"
自定义实例提供程序
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)
{
//...
}
}
,当我运行代码时,我得到了这个:
提供的服务类型无法作为服务加载,因为它 没有默认(无参数)构造函数。修复 问题,向类型添加默认构造函数,或传递实例 主机的类型。
我做错了什么?看起来我的实例提供程序甚至没有使用
答案 0 :(得分:1)
我终于找到了解决方案。我将我的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上,我无法以这种方式创建行为