2012-05-03 11 views
1

私はNinjectを勉強しようとしていて、とても簡単なことだと思って始めました。それを動作させることはできません。明らかに、私は何か基本的なものを欠いている。接続文字列注射

私はこの小さなコンソールアプリケーションを使用して、特定のポートでWCF呼び出しをリッスンし、WCF経由でデータベースに保存するデータを保存します。ソリューションには3つのプロジェクトがあります:1.データアクセスライブラリ、2. WCFのもの、3.ホストとしてのコンソール。 Ninjectはまだ使用されていません。したがって、プロジェクト間の依存関係は次のようになります:3 - > 2 - > 1

コンソールホストが設定からデータアクセスライブラリに取り込む接続文字列を注入することから始めたいと思います。接続ストリングの突き刺しのためのグーグルではいくつかの例がありましたが、完全ではありません。 ConnectionStrinProviderが唯一のプロパティのConnectionStringを含む単純なクラスです

static void Main(string[] args) 
{ 
    new StandardKernel().Bind<ConnectionStringProvider>().ToConstant(
    new ConnectionStringProvider { ConnectionString = Config.ConnectionString }); 
} 

例の一つは、次のように)ホストのメイン(にバインドするために提案しました。私が理解できないことは、データアクセスライブラリでConnectionStrinProviderをインスタンス化する方法です。試しました

これは動作しません - つまり、バインディング中に作成されたものの代わりにプロバイダの新しいインスタンスを返すことを意味します。私はまた、同じ結果で.InSingletonScope()をバインディングに追加しようとしました。

答えて

1

カーネルはすべてのバインディングを追跡します。ただし、毎回新しいインスタンスを作成しています。それは動作しません。代わりに、カーネルを作成し、それをオフに保存する(私はローカル変数にそれを格納していますここでは、しかし、あなたはおそらく、いくつかのクラスのフィールドでそれを保存したいと思います):

var connectionStringProvider = new ConnectionStringProvider { ConnectionString = Config.ConnectionString }; 
var kernel = new StandardKernel().Bind<ConnectionStringProvider>().ToConstant(connectionStringProvider); 

を今すぐインスタンスを取得します既存のカーネルにアクセスしてください。このパターンは、依存性注入のアンチテーゼであるサービスロケータパターンとして知られているように、この方法でそれを使用して、言われていること

var csprovider = kernel.Get<ConnectionStringProvider>(); 

は、それについて移動する間違った方法です。一般に、Kernel.Getによって取得されるかKernel.Injectで注入されるトップレベルクラス(たとえば、Mainメソッドを持つアプリケーションクラス)があり、他のすべての依存関係はコンストラクタまたは[Inject]のプロパティによって正常に注入されます。

また、ほとんどの状況でusually plugins availableがあるため、カーネルを自分でインスタンス化する必要はありません。しかし、私はコンソールアプリケーションのための1つを認識していない。

+0

あなたは間違った方法で目標を達成する方法のコード例を提供できますか?私がこれまでに見た例では、Mainにあるものをバインドし、カーネル変数がどこから来るのかを説明せずにkernel.Get()を呼び出して他のモジュールの依存関係を解決しています。それをコンソールアプリケーションのいくつかのクラスの静的メンバーとして公開すると、データアクセスライブラリからコンソールapp(1 - > 3)への依存関係が作成されます。これは私の意見では、まずNinjectを使用する目的を打ち負かします。カップリングを減少させる)。 – user1373607

+0

より完全な例を提供できてうれしく思いますが、データアクセスライブラリとのやりとりの仕方を詳しく説明できますか? DALでインスタンスを作成/呼び出す場所のコードを(質問を編集して)表示できますか?また、 'ConnectionStringProvider'を取得した行の周りにもう少しコンテキスト(周囲のクラスのような)を提供できますか? –

2

設定したカーネルへの参照を保持する必要があります。毎回インスタンス化すると動作しません。 consummer側

public static IKernel Ninject {get; private set;} 
static void Main(string[] args) 
{ 
    Ninject = new StandardKernel() 
    Ninject.Bind<ConnectionStringProvider>().ToConstant(
    new ConnectionStringProvider { ConnectionString = Config.ConnectionString }); 
} 

、あなたはあなたのメインの上Ninject静的プロパティを呼び出すことができます。

明らかに注意してください:これはサンプルコードです。実動コードでは、そのグローバルスタティック変数のより良い設計をしたいかもしれません。

+0

これは、データアクセスライブラリからコンソールアプリケーション(1 - > 3)への逆依存関係を作成します。これは、私の考えでは、最初にNinjectを使用する目的(結合を減らすこと)を打ち負かします。 – user1373607

+0

真。それはすべてについての明白なメモでした。 'StandarKernel' ctorは設定モジュールのオーバーロードを提供します。ソフトウェアの各レイヤーは、この設定モジュールの1つ以上を提供する必要があります。上のKirkが言ったように、サービスを求めるためにレイヤー1で直接カーネルを参照する必要はありません。サービスは1に注入する必要があります。 –