为了账号安全,请及时绑定邮箱和手机立即绑定

将数据注入WCF服务

将数据注入WCF服务

富国沪深 2019-12-27 10:22:32
我有如Miguel Castro建议的那样构造的WCF服务。这意味着我已经手动设置了所有内容,并拥有一个使用ServiceHost对象托管我的服务的控制台应用程序。我想让我的服务类保持精简,并且它们当前只是传递对行为类的调用。我现在的问题是对服务类进行单元测试。我想向类中注入一些东西作为构造函数参数,这样我就可以模拟掉它并编写适当的隔离单元测试。ServiceHost类似乎不接受参数,所以我的问题是如何将数据注入服务类中?
查看完整描述

3 回答

?
临摹微笑

TA贡献1982条经验 获得超2个赞

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来实现依赖注入。


查看完整回答
反对 回复 2019-12-27
?
慕哥6287543

TA贡献1831条经验 获得超10个赞

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


查看完整回答
反对 回复 2019-12-27
?
侃侃尔雅

TA贡献1801条经验 获得超15个赞

您是否将服务配置为Singleton?我发现使用DI容器创建服务实例时,IInstanceProvider实现可能会出现问题。


查看完整回答
反对 回复 2019-12-27
  • 3 回答
  • 0 关注
  • 603 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信