使用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);
}
}
}
}
显然,我可以使用Lazy Enumeration枚举所有IFoos并检查元数据,但不能将运行时参数传递给Lazy.Value。似乎我需要以某种方式传入Enumerable of Func&lt;&gt; s,但无法弄清楚如何附加元数据。或许我需要一种完全不同的方法?
让我的脑袋缠绕着autofac,并希望有一个干净的方法来实现这一目标。如果有一种简单的方法可以枚举所有这些(不创建它们),我可以选择使用具体的Foo类型(而不是元数据),并使用类型+运行时ID作为我的键。
答案 0 :(得分:0)
使用有效的解决方案更新了代码。想出如何使用元数据正确注册工厂。似乎工作。