使用 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 的组件。我需要为给定的运行时参数创建所有 IFoos,并且需要在创建之前检查现有实例(基本上使用 Metadata + 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);
}
}
}
}
显然,我可以使用惰性枚举枚举所有 IFoo 并检查元数据,但不能将运行时参数传递给 Lazy.Value。似乎我需要以某种方式传入一个 Func<> 的 Enumerable,但无法弄清楚如何附加元数据。或者也许我需要一种完全不同的方法?
只是让我的头围绕着autofac,并希望有一种干净的方法来实现这一点。如果有一种简单的方法可以枚举所有它们(而不创建它们),我可以只使用具体的 Foo 类型(而不是元数据),而是使用类型 + 运行时 Id 作为我的键。