1

免責事項:私はDIとIoCにはかなり新しいので、大きな誤解を許してください。Ninjectにコンストラクタの依存関係を提供すると解決できませんか?

IClassAを実装するオブジェクトが必要なClassBを考えてみましょう。 Ninjectは、それがClassAのインスタンスを構築することが可能と仮定すると、ClassBのコンストラクタにClassAのインスタンスを注入することができるはずです。

public class ClassA : IClassA 
{ 
    public ClassA(string runtimeDependency) { /* ... */ } 
} 

public class ClassB : IClassB 
{ 
    public ClassB(IClassA depA) { /* ... */ } 
} 

public sealed class TestBootstrapModule : NinjectModule 
{ 
    public override void Load() 
    { 
     Bind<IClassA>().To<ClassA>(); 
     Bind<IClassB>().To<ClassB>(); 
    } 
} 

それでは、いくつかのランタイム・ロジックがClassAに提供string runtimeDependencyの導出に関与しているとしましょう。 NinjectにruntimeDependencyを提供するには、のインスタンスを持つClassBを提供するにはどうすればよいですか?

文字列は一度しか決定されないため、各インスタンスに新しい値を挿入することについて心配する必要はありません。

答えて

2

一つの方法は、方法を介してClassAを提供することです。また、Ninject 2では、モジュールは必要なく、カーネル内で直接バインディングを行うことができます。とき、私は本当にへと刺しを取っている

Bind<IClassA>().ToMethod(_ => 
    { 
    // do something interesting with a runtimeDependancy 
    return new ClassA(someInterestingVariable); 
    }); 

ランタイム変数が利用可能であり、それはスコープです。

+0

私は可変寿命と範囲を述べてうれしいです。変数がバインディングの時点でまだ存在しない場合はどうすればよいですか? (私はすべてのバインディングを初期の場所と共通の場所で初期化する必要があると信じています) – Rob

+1

@robjb:これはデザイン問題のように思えます。それ以上の文脈がなければ、言うことは難しいでしょう。あなたは一度文字列を決定しているだけなので、それが設定された後で*あなたの束縛を行うか、あなたの束縛を行う必要があります。念頭に置いて、私は決してNinjectの専門家ではありません。 – Marc

0

ここでは、デザインや特定の問題によっていくつかのオプションがあります。まず、最も簡単な解決策は、しかし、物事はもう少し面白くこれが不可能な場合は、

Kernel.Get<IClassA>("runtimeDependencyValue"); 

Ninject

から、あなたのサービスを要求するときだけで価値を提供することです。これまでに解決した方法は、実際に System.Stringへのコンテキストバインディングを作成することです。

私は、接続文字列をバインドしたい場合、私はカスタム属性を作成しますセイ:

[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property, AllowMultiple = false, Inherited = true)] 
public class ConnectionStringAttribute : Attribute  
{ 
    /// <summary> 
    /// Denotes the setting that you want to populate the given property with. 
    /// </summary> 
    public string SettingName { get; private set; } 

    public ConnectionStringAttribute(string configSettingName = "") 
    { 
     SettingName = configSettingName; 
    } 
} 

、その後、私はこのように私のサービスのコンストラクタを飾る:私は、バインディング、最後に

public class ClassA : IClassA 
{ 
    public ClassA([ConnectionString("AppDB")] string runtimeDependency) { /* ... */ } 
} 

Bind<string>() 
    .ToMethod(ctx => 
    { 
     var attr = (ConnectionStringAttribute)context.Request.Target.GetCustomAttributes(typeof(ConnectionStringAttribute), true).First(); 
     string settingName = string.IsNullOrEmpty(attr.SettingName) ? context.Request.Target.Name : attr.SettingName; 
     return ConfigurationManager.ConnectionStrings[settingName].ConnectionString; 
    }) 
    .WhenTargetHas<ConnectionStringAttribute>(); 

あなたはこのアイデアを得るでしょう。これが助けて欲しいと思っています:)

関連する問題