Autofacのドキュメントには、デリゲート ファクトリを自動的に生成する機能を説明する興味深いページがあります。また、Autofac を使用せずに手書きで同様の結果を得ることができることも強く示唆しています。
Unity を IoC に使用していますが、他のオブジェクトを作成する必要があるオブジェクトにコンテナーを渡すのを避けたいのですが、Autofac なしでデリゲート ファクトリを作成するにはどうすればよいでしょうか?
Autofacのドキュメントには、デリゲート ファクトリを自動的に生成する機能を説明する興味深いページがあります。また、Autofac を使用せずに手書きで同様の結果を得ることができることも強く示唆しています。
Unity を IoC に使用していますが、他のオブジェクトを作成する必要があるオブジェクトにコンテナーを渡すのを避けたいのですが、Autofac なしでデリゲート ファクトリを作成するにはどうすればよいでしょうか?
これまで Unity を使用したことがないので、私の答えはかなりあいまいです。
プリンシパルは単純です。ファクトリを表すいくつかのデリゲートを定義します。次に、デリゲートに一致するパブリック メソッドを持つ「ファクトリ」クラスを作成します。このクラスはコンテナを認識しています。次に、デリゲートを登録し、そのクラスを実装として設定します。次に、デリゲートのみを注入できます。注入されたデリゲートを呼び出すと、ファクトリ クラスが呼び出されます。これにより、コンテナーが認識され、コンテナーに新しいインスタンスが要求されます。
まず、ファクトリ デリゲートを定義します。
public delegate TServiceType Provider<TServiceType>();
public delegate TServiceType Provider<TArg,TServiceType>(TArg argument);
ジェネリック ファクトリを作成すると、次のようになります。
/// <summary>
/// Represents a <see cref="Provider{TArg,TServiceType}"/> which holds
/// the container context and resolves the service on the <see cref="Create"/>-call
/// </summary>
internal class GenericFactory{
private readonly IContainer container;
public ClosureActivator(IContainer container)
{
this.container= container;
}
/// <summary>
/// Represents <see cref="Provider{TServiceType}.Invoke"/>
/// </summary>
public TService Create()
{
return container.Resolve<TService>();
}
/// <summary>
/// Represents <see cref="Provider{TArg,TServiceType}.Invoke"/>
/// </summary>
public TService Create(TArg arg)
{
return container.Resolve<TService>(new[] {new TypedParameter(typeof (TArg),arg)});
}
}
デリゲートを登録すると、次のようになります。
var newServiceCreater = new GenericFactory(container);
container.Register<Provider<MyCompoent>>().To(newServiceCreater.Create);
var newServiceCreater = new GenericFactory(container);
container
.Register<Provider<OtherServiceWithOneArgumentToConstruct>>()
.To(newServiceCreater.Create);
これで、コンテナの代わりに「プロバイダ」だけを他のコンポーネントに注入できます。