3

Castle Windsor を使用するレポート MVC アプリケーションがあります。

アプリケーションの起動時 (global.asax 内) にすべてのタイプが登録され、アプリケーションへの後続の各要求が関連するレポート タイプを解決し、windsor が依存関係を自動的に処理します。

リクエストで渡されたパラメーターに応じて、依存型の 1 つを別の型に切り替える必要があります。

どうすればこれを達成できますか?

切り替え可能な型の解決を処理するために Windsor にファクトリ メソッドを登録しましたが、これはアプリケーションの開始時に登録されるため、パラメータが後のリクエストでしか使用できない場合、どうすればファクトリ メソッドにパラメータを渡すことができますか?

リクエストごとにファクトリを登録しようとすると、最初のリクエストでは機能しますが、その後のすべてのリクエストではファクトリがすでに登録されていると不平を言います。各リクエストの後にファクトリを登録解除することは、正しいことのようには思えません。

4

4 に答える 4

2

ファクトリにはTypedFactoryFacilityを使用します。

次の 2 つの方法があります。

デフォルトの規則では、「CustomFoo」という名前で登録されたコンポーネントがある場合、2 番目のメソッドはそのコンポーネントを解決しますが、最初のメソッドはデフォルトのコンポーネントを取得します。

public interface IFooFactory
{
   IFoo GetFoo(...arguments);
   IFoo GetCustomFoo(..arguments);

   void ReleaseFoo(IFoo foo);
}
于 2010-09-23T01:10:57.230 に答える
2

実行時に型を解決する必要がある場合、通常の解決策は、適切なタイミングで決定できるファクトリを注入することです。

public class ReportFactory: IReportFactory {
    IReport CreateReport(bool useDefault) {
        if (useDefault) {
            return new DefaultReport();
        } else {
            return new UnusualReport();
        }
    }
}

以前は を要求していたクラスは、代わりにIReportを要求する必要がありIReportFactoryます。

于 2010-09-22T16:52:24.353 に答える
2

リクエストごとにコンテナを変更したくないことは間違いありません。それは災害のレシピです。

2 つのオプションがあります。1 つ目は、ファクトリ メソッド内で HttpContext.Current を使用することです。

IWhatever CreateWhatever() {
     if (HttpContext.Current.Request["parameter"] == "value-for-other-whatever")
       return new FirstWhatever();

     return DefaultWhatever();
}

もう 1 つの (より良い) オプションは、コンテナーに実行させるのではなく、正しい実装を解決するファクトリ型を注入することです。

public class WhateverFactory : IWhateverFactory {
     public IWhatever GetWhatever(string parameter) {
         if(parameter == "value for other whatever")
            return new OtherWhatever();

         return new DefaultWhatever();
     }
}

次に、コントローラはファクトリのインスタンスを取得し、インスタンス化するタイプをファクトリに決定させます。

于 2010-09-22T16:57:13.953 に答える
1

Mike Hadlow のブログで、ウィンザーに登録されたデリゲートを使用して、多数の名前付き型登録の 1 つを返す記事を見つけました...

したがって、基本的にウィンザー登録は次のようになります...

     container
            .Register(
                    Component.For<IReportFormatter>().ImplementedBy<ReportFormatterWord2003>().Named("word2003"),
                    Component.For<IReportFormatter>().ImplementedBy<ReportFormatterWord2007>().Named("word2007"),
                    Component.For<IReportFormatter>().ImplementedBy<ReportFormatterPdf>().Named("pdf"),
                    Component.For<Func<string, IReportFormatter>>().Instance(container.Resolve<IReportFormatter>),
                    Component.For<Foo>());

Foo コンストラクターはデリゲート型のパラメーターを受け取ります

Foo(Func<string, IReportFormatter> reportFormatterFactory)

Windsor が Foo を解決するとき、reportFormatterFactory は IReportFormatter の実装に解決されず、代わりに単に container.Resolve メソッドへの参照を保持します...

container.Resolve<IReportFormatter>(string)

後で呼び出して正しい IReportFormatter を取得するために使用できます...

reportFormatterFactory("word2007");

ファクトリを登録するほど理解しにくいかもしれませんが、ファクトリ クラスは不要です。

于 2011-01-14T14:57:56.480 に答える