2012-04-02 3 views
2

私はNinject工場拡張を使用して、カスタムインスタンスプロバイダを作成していますがウィキで説明:Ninjectファクトリーカスタムインスタンスプロバイダ

interface IFooFactory 
{ 
    IFoo NewFoo(string template); 
} 

class UseFirstArgumentAsNameInstanceProvider : StandardInstanceProvider 
{ 
    protected override string GetName(System.Reflection.MethodInfo methodInfo, object[] arguments) 
    { 
     return (string)arguments[0]; 
    } 

    protected override Parameters.ConstructorArgument[] GetConstructorArguments(System.Reflection.MethodInfo methodInfo, object[] arguments) 
    { 
     return base.GetConstructorArguments(methodInfo, arguments).Skip(1).ToArray(); 
    } 
} 

私は、次のファクトリインタフェースを定義しました私は以下のバインディングを作成しました:

kernel.Bind<IFooFactory>().ToFactory(() => new UseFirstArgumentAsNameInstanceProvider()); 
kernel.Bind<IFoo>().To<FooBar>().Named("Foo"); 

ここで私は次のインスタンスを取得します。 FooBar

var foobar = fooFactory.NewFoo("Foo"); 

これはすべて素晴らしいです。私が希望することはしかし、もう少し、このようなものです:

interface IFooTemplateRepository 
{ 
    Template GetTemplate(string template); 
} 

私は名前(「foo」という)に基づいてテンプレートを戻すことがリポジトリを持っていると私は、コンストラクタの引数としてテンプレートを渡したいです。

public class FooBar 
{ 
    public FooBar(Template template) 
    { 
    } 
} 

これは可能ですか?私はITemplateRepositoryに何が依存するべきか分からない。

答えて

1

エンティティのインスタンスを作成するためにIoCコンテナを使用しないでください。これはビジネスロジックなので、コンポジションルートには属しません。これを処理する正しい方法は、ORMを直接使用することです(使用しているリポジトリパターンなど)。

var template = this.templateRepository.Get("SomeTemplate"); 
var fooBar = this.fooBarFactory.CreateFooBar(template); 
+0

私はそれを思っていました。私はおそらく最初のパラメータをテンプレートに変換し、その上のプロパティを調べて、どの名前付きインスタンスを作成するかを決定するカスタムプロバイダを作成できます。 – Dismissile