14

IConfigアプリケーション全体で使用される設定を含むオブジェクトがあります。現時点では、次のように、オブジェクト全体を、それを必要とする各オブジェクトのコンストラクターに挿入します。

public interface IConfig 
{
    string Username { get; }
    string Password { get; }
    //... other settings
}

public class Foo : IFoo
{
    private readonly string username;
    private readonly string password;

    public Foo(IConfig config)
    {
        this.username = config.Username;
        this.password = config.Password;
    }
}

欠点は、IConfig構成ファイル全体から逆シリアル化されているため、多数の設定が含まれているため、オブジェクト全体を注入する必要がないことです。私がやりたいのはFoo(string username, string password)、必要な設定のみを受け取るようにコンストラクターを変更することです。これにより、テスト用のオブジェクトの作成もはるかに簡単になります (作成するためだけにFoo設定する必要はありません)。次のように、コンストラクターの引数を my に直接バインドしたいと思います。IConfigFooNinjectModule

public class MyModule : NinjectModule
{
    public override void Load()
    {
        Bind<IConfig>().To<JsonConfig>()
            .InSingletonScope();

        Bind<IFoo>().To<Foo>()
            .WithConstructorArgument("username", IConfig.Username)
            .WithConstructorArgument("password", IConfig.Password);
    }
}

明らかに、このコードは機能しませんが、どうすればやりたいことを実行できるでしょうか?

私の最初のアイデアは、 を使用してオブジェクトのインスタンスを取得し、NinjectModule.Kernel必要に応じてプロパティを注入することでしたが、 によって返されるオブジェクトにはメソッドがありません。IKernelIConfigNinjectModule.KernelGet<T>()

4

2 に答える 2

15

あなたは正しい軌道に乗っています:

このメソッドは、名前空間のでKernel.Get<T>()定義された拡張メソッドであるため、 を追加すると、モジュールでも使用できます。ResolutionExtensionsNinjectusing Ninject;

ただし、 の代わりに、の 2 番目のオーバーロードで提供されているModule.Kernelを使用して、を取得する必要があります。IContextWithConstructorArgumentKernel

Bind<IFoo>().To<Foo>()
    .WithConstructorArgument("username", 
                             context => context.Kernel.Get<IConfig>().Username)
    .WithConstructorArgument("password", 
                             context => context.Kernel.Get<IConfig>().Password);
于 2012-05-19T07:05:03.337 に答える
1

これは、インターフェイス分離の原則の良い候補となる可能性があります。

この場合、とプロパティICredentialConfigだけを含むなどの別のインターフェイスを定義してから、このインターフェイスを実装します。UsernamePasswordIConfig

public Interface ICredentialConfig
{
   string Username { get; }
   string Password { get; }
}

public Interface IConfig : ICredentialConfig
{
   //... other settings
}

の代わりにFoo依存するようになりました。その後、次のことができます。ICredentialConfigIConfig

  1. JsonConfigパラメータ名をハードコーディングする代わりに、Ninject を使用して注入します。
  2. 完全なインターフェースを実装する代わりに、テストでICredentialConfigインスタンス化するために を実装/モックします。FooIConfig
于 2015-03-12T05:05:52.523 に答える