Autofacを使用して、コンストラクターで実行時パラメーターを受け取る複数のIFooコンポーネントがあります。実行中のインスタンスを構築および管理するために、実行時パラメーターとともにタイプのメタデータを使用しています。
interface IFoo
{
int RunTimeId { get; }
}
[FooMeta("ShaqFoo")]
class Foo1 : IFoo
{
public Foo1 (int runtTimeId)
{
...
}
[FooMeta("KungFoo")]
class Foo2 : IFoo
{
public Foo2 (int runtTimeId)
{
...
}
モジュール/登録のようなもの:
builder.Register<Func<int, Foo1>>(c =>
{
var cc = c.Resolve<IComponentContext>();
return id => cc.Resolve<Foo1>(TypedParameter.From<int>(id));
})
.As<Func<int, IFoo>>()
.WithMetadata<IFooMetaData>(m => m.For(sm => sm.FooType, typeof(Foo1)));
builder.Register<Func<int, Foo2>>(c =>
{
var cc = c.Resolve<IComponentContext>();
return id => cc.Resolve<Foo2>(TypedParameter.From<int>(id));
})
.As<Func<int, IFoo>>()
.WithMetadata<IFooMetaData>(m => m.For(sm => sm.FooType, typeof(Foo2)));
また、ランタイムパラメータとメタデータを使用して新しいFoosを作成するコンポーネント。特定のランタイムパラメータに対してすべてのIFooを作成する必要があり、作成する前に既存のインスタンスをチェックする必要があります(基本的にメタデータ+ RunTimeIdをキーとして使用)。
public class FooActivator
{
public FooActivator(IEnumerable<Lazy<Func<int, IFoo>, IFooMetaData>> fooFactories)
{
m_FooFactories = fooFactories;
}
private void HandleNewRunTimeIdEvent(int id)
{
CreateFoosForNewId(id);
}
private void CreateFoosForNewId(int id)
{
foreach (var fooFactory in m_FooFactories)
{
if (!FooWithThisMetadataAndIdExists(fooFactory.Metadata.FooType, id))
{
var newFoo = fooFactory.Value(id);
}
}
}
}
明らかに、Lazy Enumerationを使用してすべてのIFooを列挙し、メタデータを確認することはできますが、実行時パラメーターをLazy.Valueに渡すことはできません。どういうわけか、Enumerable of Func <>を渡す必要があるようですが、メタデータを添付する方法がわかりません。それとも、まったく異なるアプローチが必要ですか?
私の頭をautofacに巻き付けて、これを達成するためのクリーンな方法があることを願っています。すべてを(作成せずに)列挙する簡単な方法があれば、(メタデータの代わりに)具体的なFooタイプを使用するだけで解決でき、代わりにタイプ+ランタイムIDをキーとして使用できます。