1. ホーム
  2. c#

DIとコンストラクタのパラメータを組み合わせる?

2023-08-15 11:58:20

質問

コンストラクタ注入と手動コンストラクタ・パラメータを組み合わせるにはどうしたらよいでしょうか。

public class SomeObject
{
    public SomeObject(IService service, float someValue)
    {
    }
}

IServiceはDIコンテナによって解決/注入される必要があり、someValueは指定される必要があります。この2つを混ぜるにはどうしたらよいでしょうか?

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

このような構成は可能な限り避けるべきです。したがって、自分自身に問いかけてみてください。このパラメータはコンストラクタの引数として本当に必要なのでしょうか?または、オブジェクト上で実行するメソッドにパラメータを渡すことで、SomeObject をそれに依存するすべての人によって再利用されるステートレスなものに置き換えることができるでしょうか。

例:代わりに

public class SomeObject
{
    private float someValue
    public SomeObject(IService service, float someValue)
    {
        this.someValue = someValue
    }

    public float Do(float x)
    {
        return this.Service.Get(this.someValue) * x;
    }
}

使用

public class SomeObject
{
    public SomeObject(IService service)
    {
    }

    public float Do(float x, float someValue)
    {
        return this.Service.Get(someValue) * x;
    }
}


必要であれば、工場に行く。

public interface ISomeObjectFactory
{
    ISomeObject CreateSomeObject(float someValue);
}

public class SomeObjectFactory : ISomeObjectFactory
{
    private IKernel kernel;
    public SomeObjectFactory(IKernel kernel) 
    {
        this.Kernel = kernel;
    }

    public ISomeObject Create(float someValue)
    {
        return this.kernel.Get<ISomeObject>(WithConstructorArgument("someValue", someValue);
    }
}

プレビューです。 Ninject 2.4では実装は必要なくなりますが

kernel.Bind<ISomeObjectFactory>().ToFactory();  // or maybe .AsFactory();