1. ホーム
  2. wcf

[解決済み] wcf サービスのコンストラクタに値を渡すにはどうすればよいですか?

2022-11-09 20:22:47

質問

サービスを実装するクラスのコンストラクタに値を渡したいのですが、どうすればよいですか?

しかし、ServiceHostは作成する型の名前を渡すだけで、そのコンストラクタに渡す引数を指定することはできません。

私は自分のサービスオブジェクトを作成するファクトリーに渡すことができるようにしたいと思います。

今までに見つけたもの

  • WCF依存性注入の動作 これは私が探しているものよりも多く、私のニーズに対して複雑になりすぎているようです。

どのように解決するのですか?

を組み合わせて実装する必要があります。 ServiceHostFactory , ServiceHostIInstanceProvider .

このコンストラクタのシグネチャを持つサービスがあるとします。

public MyService(IDependency dep)

MyServiceをスピンアップする例です。

public class MyServiceHostFactory : ServiceHostFactory
{
    private readonly IDependency dep;

    public MyServiceHostFactory()
    {
        this.dep = new MyClass();
    }

    protected override ServiceHost CreateServiceHost(Type serviceType,
        Uri[] baseAddresses)
    {
        return new MyServiceHost(this.dep, serviceType, baseAddresses);
    }
}

public class MyServiceHost : ServiceHost
{
    public MyServiceHost(IDependency dep, Type serviceType, params Uri[] baseAddresses)
        : base(serviceType, baseAddresses)
    {
        if (dep == null)
        {
            throw new ArgumentNullException("dep");
        }

        foreach (var cd in this.ImplementedContracts.Values)
        {
            cd.Behaviors.Add(new MyInstanceProvider(dep));
        }
    }
}

public class MyInstanceProvider : IInstanceProvider, IContractBehavior
{
    private readonly IDependency dep;

    public MyInstanceProvider(IDependency dep)
    {
        if (dep == null)
        {
            throw new ArgumentNullException("dep");
        }

        this.dep = dep;
    }

    #region IInstanceProvider Members

    public object GetInstance(InstanceContext instanceContext, Message message)
    {
        return this.GetInstance(instanceContext);
    }

    public object GetInstance(InstanceContext instanceContext)
    {
        return new MyService(this.dep);
    }

    public void ReleaseInstance(InstanceContext instanceContext, object instance)
    {
        var disposable = instance as IDisposable;
        if (disposable != null)
        {
            disposable.Dispose();
        }
    }

    #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
}

MyService.svc ファイルに MyServiceHostFactory を登録するか、セルフホスティングのシナリオではコード内で直接 MyServiceHost を使用します。

この方法は簡単に一般化でき、実際、いくつかのDI Containersはすでにこれを実行しています(出典:WindsorのWCF Facility)。