sti*_*k81 20 .net service wcf unit-testing dependency-injection
我有像Miguel Castro建议的WCF服务结构.这意味着我已手动设置所有内容,并使用ServiceHost对象托管我的服务的控制台应用程序.
我想保持我的服务类很薄,他们目前只是调用行为类.我现在的问题是单元测试服务类.我想向类中注入一些东西作为构造函数参数,这样我就可以模拟它并编写适当的隔离单元测试.ServiceHost类似乎不接受参数,所以我的问题是如何将数据注入服务类 - 或者我不能?
Mar*_*ann 32
WCF支持构造函数注入,但你必须跳过几个环节才能到达那里.关键在于编写自定义ServiceHostFactory.虽然这也必须有默认构造函数,但您可以使用它来连接所有正确的行为.
作为一个例子,我最近写了一个使用Castle Windsor来连接服务实现的依赖关系.CreateServiceHost的实现只是这样做:
return new WindsorServiceHost(this.container, serviceType, baseAddresses);
Run Code Online (Sandbox Code Playgroud)
哪里this.container
是配置的IWindsorContainer.
WindsorServiceHost看起来像这样:
public class WindsorServiceHost : ServiceHost
{
public WindsorServiceHost(IWindsorContainer container, Type serviceType, params Uri[] baseAddresses)
: base(serviceType, baseAddresses)
{
if (container == null)
{
throw new ArgumentNullException("container");
}
foreach (var cd in this.ImplementedContracts.Values)
{
cd.Behaviors.Add(new WindsorInstanceProvider(container));
}
}
}
Run Code Online (Sandbox Code Playgroud)
和WindsorInstanceProvider看起来像这样:
public class WindsorInstanceProvider : IInstanceProvider, IContractBehavior
{
private readonly IWindsorContainer container;
public WindsorInstanceProvider(IWindsorContainer container)
{
if (container == null)
{
throw new ArgumentNullException("container");
}
this.container = container;
}
#region IInstanceProvider Members
public object GetInstance(InstanceContext instanceContext, Message message)
{
return this.GetInstance(instanceContext);
}
public object GetInstance(InstanceContext instanceContext)
{
var serviceType = instanceContext.Host.Description.ServiceType;
return this.container.Resolve(serviceType);
}
public void ReleaseInstance(InstanceContext instanceContext, object instance)
{
this.container.Release(instance);
}
#endregion
#region IContractBehavior Members
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)
{
}
#endregion
}
Run Code Online (Sandbox Code Playgroud)
这可能看起来很多,但请注意它是可重复使用的通用代码,具有相当低的圈复杂度.
您可以遵循相同的编码习惯用另一个DI容器或使用穷人的DI实现依赖注入.
这是使用穷人的DI的这个成语的较旧的写作.
归档时间: |
|
查看次数: |
12936 次 |
最近记录: |