2

現在、Ninject を使用していくつかのフィールドの初期値を設定する方法を考え出そうとしています。

私はこのようなものを持っています:

public class SomeClass
{
    private ISomething _something;

    public SomeClass(string someParam)
    {

    }

    public void DoAThing()
    {
        _something.DoSomething();
    }
}

私のジレンマは_something、初期値への設定で発生します。クラスに、使用する のデフォルト実装について何も知られたくないのですがISomething、Ninject でこれを達成する方法はありますか?

コンストラクターを介して初期値を渡すことはオプションではないことを付け加えておきます。

また、これはクラスライブラリにあることも付け加えておく必要があるため、カーネルとインジェクションのセットアップ方法とタイミングに関する情報は素晴らしいでしょう:)

詳細: 人々が混乱している可能性があるようです。私は ISomething をクラスに取り込もうとはしていません (依存関係ではありません)。むしろ、ISomething のデフォルトの実装は依存関係です。これが、私がサービスを利用した理由です。 -locator パターン。実際の依存関係については、もちろんコンストラクターに含めます。

ありがとう。

4

2 に答える 2

1

はい、高度に結合されたクラスを持つことはあまり良くありません。したがって、抽象化に依存することは良い選択です。しかし、依存関係を隠すことはあまり良い解決策ではありません。それらをクラスのクライアントに表示し、依存性注入を使用して、クラスに依存関係の具体的な実装を提供します。

public class SomeClass
{
    private ISomething _something;

    public SomeClass(ISomething something, string someParam)
    {
        _something = something;
    }

    public void DoAThing()
    {
        _something.DoSomething();
    }
} 

ISomethingまた、ファクトリを作成することも検討してください。ファクトリは、作成されたオブジェクトのデフォルトの実装を提供しますSomeClass

于 2012-12-02T22:48:52.163 に答える
0

最終的に、静的 IOC アクセス クラスを使用して、コードがメイン インジェクション用のクラス ライブラリによって使用されるコア Ninject カーネルにアクセスできるようにすることにしました。

そう:

internal static class IOC
{
    private static readonly IKernel _kernel;

    static IOC()
    {
        _kernel = new StandardKernel(new IModule[] {
            new SomethingModule(),
        });
    }

    static T Get<T>()
    {
        return _kernel.Get<T>();
    }
}

internal sealed class SomethingModule : StandardModule
{
    public override void Load()
    {
        Bind<ISomething>().To<ConcreteSomething>(
            new ConstructorParam("arg", "value"));
    }
}

それから私の前のクラスで:

public class SomeClass
{
    private ISomething _something;

    public SomeClass(string someParam)
    {
        _something = IOC.Get<ISomething>();
    }

    public void DoAThing()
    {
        _something.DoSomething();
    }
}

これで、具体的な実装を取得し、デフォルト値で初期化して起動することさえできます!

デフォルト値で初期化された具体的なクラスを取得する方法は少し薄っぺらですが、Ninject でこれを実現するよりスマートな方法があると確信していますが、サービス ロケーター風のコードと Ninject のハイブリッド ソリューションは非常に機能するようです。良い!

ところで、巨大な「どこにでもある」カーネルの作成を防ぐために、複数の IOC コンテナーを異なるスコープ (Ninject :P 経由で渡される) に配置することもできると思います。

これが誰かを助けたことを願っています!

于 2012-12-02T22:39:43.270 に答える