猿问

将数据注入WCF服务

我有如Miguel Castro建议的那样构造的WCF服务。这意味着我已经手动设置了所有内容,并拥有一个使用ServiceHost对象托管我的服务的控制台应用程序。


我想让我的服务类保持精简,并且它们当前只是传递对行为类的调用。我现在的问题是对服务类进行单元测试。我想向类中注入一些东西作为构造函数参数,这样我就可以模拟掉它并编写适当的隔离单元测试。ServiceHost类似乎不接受参数,所以我的问题是如何将数据注入服务类中?


富国沪深
浏览 604回答 3
3回答

临摹微笑

WCF支持构造函数注入,但是您必须跳过几个步骤才能到达那里。关键在于编写自定义ServiceHostFactory。尽管它也必须具有默认构造函数,但是您可以使用它构造所有正确的行为。作为示例,我最近写了一篇使用Castle Windsor来为服务实现连接依赖关系的示例。CreateServiceHost的实现只是这样做:return new WindsorServiceHost(this.container, serviceType, baseAddresses);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));        }    }}和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}这看起来可能很多,但是请注意,它是可重用的通用代码,其循环复杂度较低。您可以遵循相同的编码习惯,使用另一个DI容器或使用穷人的DI来实现依赖注入。

慕哥6287543

如果您使用的是Castle Windsor,它具有出色的WCF集成功能,可以让您轻松地做到这一点。

侃侃尔雅

您是否将服务配置为Singleton?我发现使用DI容器创建服务实例时,IInstanceProvider实现可能会出现问题。
随时随地看视频慕课网APP
我要回答