2011-11-08 6 views
3

現在キャッスルウィンザーの子コンテナ機能を使用して、ファクトリメソッドで特定のインスタンスの特定のインスタンスの登録をオーバーライドしています。私は子コンテナを純粋に使用しているため、登録は単一の解決のために一時的です。つまり、登録がそのタイプのすべての解決に影響することは望ましくありません。Castle Windsorの子コンテナを使用して特定のインスタンスの型を解決する

多分、いくつかのコードが私の意味を説明します。

私は工場として機能するFuncを持っていますFunc<IReportCategory, IReportCategoryViewModel> - IReportCategoryの実装を与え、IReportCategoryViewModelの新しいインスタンスを返します。 (IReportCategoryViewModelはIReportCategoryに依存します)。

次のようにこれは、城ウィンザーに登録されている:

次のように ResolveCategoryViewModelFactoryが実装されている
 container.Register(
      Component.For<Func<IReportCategory, IReportCategoryViewModel>>().Instance(
       category => ResolveCategoryViewModelFactory(container, category))); 

private CategoryViewModel ResolveCategoryViewModelFactory(IWindsorContainer container, IReportCategory category) 
    { 
     using (IWindsorContainer childContainer = new WindsorContainer()) 
     { 
      childContainer.Register(Component.For<IReportCategory>().Instance(category)); 
      container.AddChildContainer(childContainer); 

      return childContainer.Resolve<IReportCategoryViewModel>(); 
     } 
    } 

何上記の方法は達成するの特定のインスタンスを注入し、IReportCategoryViewModelの解像度を依存関係としてのIReportCategory。 IReportCategoryViewModelに満足する必要のある他の依存関係がある場合、これらはコンテナによって自動的に挿入されます。

次のように私は、その後のFuncを使用することができます。

public class Test 
{ 
    private readonly Func<IReportCategory, IReportCategoryViewModel> factory; 

    public Test(Func<IReportCategory, IReportCategoryViewModel> factory) 
    { 
     this.factory = factory; 
    } 

    public void ResolveTest() 
    { 
     // Create a category (note: this would probably be resolved from the container in some way) 
     IReportCategory category = new ReportCategory(); 

     // Call into the factory to resolve the view model 
     IReportCategoryViewModel vm = factory(category); 
    } 
    ... 

質問:はこれを行うために適切なもののように見えるのか?私が得た印象から、子供用コンテナはCastle Windsorではお勧めできません - 同じ結果を達成する別の方法がありますか?

ありがとうございました。

答えて

2

これは良い方法ですが、現在使用しているコードにはバグがあります。子コンテナを処分するときに解決しているすべてのコンポーネントインスタンスを解放しようとします。あなたがそれらを使用する機会を得る前に使用できない(処分された)。

私はあなたの説明を正しく理解すれば、typed factoriesの仕事のように感じます。

+0

これを行うには、型付きファクトリが本当に便利です。多くの人がKrzysztofに感謝します! –

+2

これは、子コンテナと同じ動作にはなりません。ファクトリメソッドの引数にコンストラクタ引数を一致させるために名前を使用するため、ファクトリ自体によって返される型に対してのみ機能します。つまり、注入が必要な場合は、インスタンスをファクトリメソッドに渡します。ここに私がこれを探求するために使ってきた要点があります(これはもっと良く説明するかもしれません)。https://gist.github.com/1357829 – GraemeF

4

Typed Factoriesを使用するためのKrzysztofのアドバイスに続いて、上記の機能をどのように実装したかを次に示します。子コンテナを使用するよりはるかに簡単です!

まず、ファクトリメソッドのシグネチャを定義ファクトリインターフェイスを作成:

public interface ICategoryViewModelFactory 
{ 
    CategoryViewModel Create(ReportCategory category); 
} 

次に、TypedFactoryFacilityが容器内に有効になっていることを確認:

container.AddFacility<TypedFactoryFacility>(); 

最後に、ファクトリインタフェースを登録しますコンテナ付き:

container.Register(
    Component.For<ICategoryViewModelFactory>() 
     .AsFactory()); 

あなたのクラスにJECT ICategoryViewModelFactory、とはCategoryViewModelの新しいインスタンスを作成するために、Create()メソッドを呼び出します。

public class SomeClass 
{ 
    public SomeClass(ICategoryViewModelFactory categoryViewModelFactory) 
    { 
     // This would probably be resolved by the container (it's like this for the example) 
     ReportCategory category = new ReportCategory(); 

     // Get Windsor to resolve the view model using the factory 
     ReportCategoryViewModel vm = categoryViewModelFactory.Create(category); 

     .... 

警告:ファクトリメソッドのパラメータ名は、オブジェクトのコンストラクタのパラメータ名と一致する必要があります工場が作成する。上記の例では、ファクトリインタフェースは、メソッドを定義します。

CategoryViewModel Create(ReportCategory category) 

CategoryViewModelのコンストラクタは、パラメータが「カテゴリ」という名前の持っている必要があります。

public CategoryViewModel(ReportCategory category) 

ファクトリメソッドが同等であるためです次のようになります。

container.Resolve<CategoryViewModel>(new { category = paramPassedIntoFactoryMethod }); 
+0

この問題を解決するために使用したコードを投稿していただきありがとうございます。このような例を探して私を助けてください。しかし、私はまだ立ち往生しています。私はあなたのコードを効果的にコピーし、オブジェクトに適切なものにするためにいくつかの言葉を置き換え、アプリケーションを実行すると、あなたの 'ReportCategory'オブジェクトに相当する' DependencyResolverException'を取得します。例外は、私のビューモデルが解決できなかったモデルに依存していることを示します。 Castle Windsorに 'ReportCatgory'を登録しましたか?もしそうなら、どうですか? – Stu

+0

私はこの問題を解決し、次の質問で自分のコードを投稿しました:http://stackoverflow.com/a/11604109/336752 – Stu

関連する問題