0

Ninjectモジュールに次のコードが数回繰り返されています。この繰り返されるコードを減らすためにどのような方法と手法を使用できますか?

public override void Load()
{
    Bind<IDataReader<IList<Price>>>()
        .To<PricesDataReader>().Named("ValDatePrices");
    Bind<IDataConnection<IList<PricesCsvRecord>>>()
        .To<PricesXLConnection>().WhenParentNamed("ValDatePrices")
        .Named("ValDatePricesXLConnection");
    Bind<IDirectoryBuilder>()
        .ToMethod(DefaultValDatePricesDirectory)
        .WhenParentNamed("ValDatePricesXLConnection");

    Bind<IDataReader<IList<Price>>>()
        .To<PricesDataReader>().Named("EDDatePrices");
    Bind<IDataConnection<IList<PricesCsvRecord>>>()
        .To<PricesXLConnection>().WhenParentNamed("EDDatePrices")
        .Named("EDDatePricesXLConnection");
    Bind<IDirectoryBuilder>()
        .ToMethod(DefaultEDDatePricesDirectory)
        .WhenParentNamed("EDDatePricesXLConnection");
}

IDirectoryBuilder主な違いは、実装を使用して構成設定に基づいてファイルの場所を決定することを主な機能とするを要求するときに発生しますIDirectory

上記の例では、を返しますが、以下DefaultDirectoryBuilderにこれらの他のいくつかの実装があります(EdNrrDirectoryBuilderメソッドを参照)。

public IDirectoryBuilder DefaultValDatePricesDirectory(IContext arg) 
{
    return new DefaultDirectoryBuilder(
         ConfigurationManager.AppSettings["VALDATE_PRICES_DIR"],
         ConfigurationManager.AppSettings["VALDATE_PRICES_FILENAME"]);
}

public IDirectoryBuilder DefaultEDDatePricesDirectory(IContext arg) 
{
    return new DefaultDirectoryBuilder(
         ConfigurationManager.AppSettings["EDDATE_PRICES_DIR"],
         ConfigurationManager.AppSettings["EDDATE_PRICES_FILENAME"]);
}

public IDirectoryBuilder EdNrrDirectoryBuilder(IContext arg)
{
    return new ExternalDirectoryBuilder(
         ValuationDate,
         ConfigurationManager.AppSettings["NRRDATE_DIR"],
         ConfigurationManager.AppSettings["NRRDATE_PRICES_FILENAME"]);
}

私の問題は、構成ファイルの値が必要なことです。現在、構成に関連するすべてのリクエストは、私のNinjectモジュールで制限されています。

Ninject Factoryアプローチを使用してsを作成する場合 、コードベース全体に関連する呼び出しを分散IDirectoryBuilderさせる必要があることがわかります。ConfigurationManager

Ninject Providerアプローチを使用する場合、IDirectoryBuildersのすべての実装にプロバイダーが必要になり、コンストラクターとの実装も更新されIDataConnectionます。私のコードも次のようになります(あまり乾燥しておらず、現在のアプローチと似ています)。

Bind<IDirectoryBuilder>().ToProvider<DefaultDirectoryBuilderProvider>()
    .WhenParentNamed("EDDatePricesXLConnection")
    .WithConstructorArgument("baseDir", "someConfigValue")
    .WithConstructorArgument("fileName", "someOtherConfigValue");

私のコードには、現時点で非常に一貫性のある依存関係チェーンがあります(NamedArgumentsを使用):ICalculator-> IDataReader-> IDataConnection-> IDirectoryBuilder-これにより、セットアップコードを繰り返さなくても、このチェーンを繰り返し作成する方法があるはずだと思います-これは可能です理解していないようです。追加の制限があり、同じ依存関係チェーンの2つのインスタンスが必要になることがよくあります。唯一の違いは、構成値が異なることです。

4

2 に答える 2

0

Ninject固有の手法に依存する理由はありません(ただし、場合によっては、プロバイダーが適切な場合があります(ここでのプロバイダーの例)。

簡単な答えは、バインディング式の前のコンポーネントが返すものの拡張メソッドを作成することです(同様の質問)。


あなたの質問を読み直すとき、私はあなたがあなたが提案する方法でブルキングをすることを可能にするたくさんの拡張メソッドを持っているNinject.Extensions.Conventionsを見ることを提案します。そうでない場合は、コメントして、対処できないと思われるビットを特定することをお勧めします。BindBind

于 2012-04-27T07:41:51.727 に答える
0

ルーベンのコメントに基づいて、これは私の現在の解決策です。私が行ったのは、規則の概念を使用することでした。これにより、構成設定の取得が簡単になりました。Namedこれは、Ninjectパラメーターを使用した他のほとんどのコードをフィルター処理しました。

public void Load(){
    BindDependencies<IDataReader<IList<Price>>, PricesDataReader
      , IDataConnection<IList<PricesCsvRecord>>, PricesXLConnection
      , DefaultDirectoryBuilder>
      ("ValDatePrices");

    BindDependencies<IDataReader<IList<Price>>, PricesDataReader
      , IDataConnection<IList<PricesCsvRecord>>, PricesXLConnection
      , DefaultDirectoryBuilder>
      ("EDDatePrices");
       // etc etc 
}

 public void BindDependencies<
     TReaderBase, TReaderImpl,
     TDataConnectionBase, TDataConnectionImpl,
     TDirectoryBuilderFactoryImpl>
     (string baseName)
         where TReaderImpl : TReaderBase
         where TDataConnectionImpl : TDataConnectionBase
 {
     DirectoryBuilderInfo dirInfor = GetSettings(baseName);

     Bind<TReaderBase>()
           .To(typeof(TReaderImpl))
           .Named(baseName);
     Bind<TDataConnectionBase>().To(typeof(TDataConnectionImpl))
            .WhenParentNamed(baseName)
            .Named(baseName + "XLConnection");
     Func<IDirectoryBuilder> directoryBuilder = CreateDirectoryBuilderFunc<TDirectoryBuilderFactoryImpl>(dirInfor);

     Bind<IDirectoryBuilder>()
            .ToMethod(d => directoryBuilder())
            .WhenParentNamed(baseName + "XLConnection");
    }

private Func<IDirectoryBuilder> CreateDirectoryBuilderFunc<TDirectoryBuilderFactoryImpl>(DirectoryBuilderInfo dirInfor)
{
    Func<IDirectoryBuilder> directoryBuilder = 
         () => CreateDefaultDirectoryBuilder(dirInfor.BaseDirectory, dirInfor.FileName);

    if (typeof(TDirectoryBuilderFactoryImpl) == typeof(RiskDirectoryBuilderFactory))
    {
        directoryBuilder = 
         () => CreateRiskDirectoryBuilder(ValuationDate, dirInfor.BaseDirectory, dirInfor.FileName);
    }
    return directoryBuilder;
}

private DirectoryBuilderInfo GetSettings(string baseName)
{
    var settingsName = baseName.ToUpperInvariant();
    return new DirectoryBuilderInfo()
    {
        BaseDirectory = ConfigurationManager.AppSettings[settingsName + "_DIR"],
        FileName = ConfigurationManager.AppSettings[settingsName + "_FILENAME"]
     };
 }
于 2012-05-03T10:20:27.057 に答える