autofac: IEnumerable<Lazy<IFoo, IFooMetaData>> --> Lazy.Value(with runtime param)?



使用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)));    

以及一个组件,该组件使用运行时参数和元数据创建新的Foo。我需要为给定的运行时参数创建ALL 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枚举枚举所有IFoos并检查元数据,但不能将运行时参数传递给Lazy。价值似乎我需要传入Func<>的枚举s,但不知道如何附加元数据。或者我需要一个完全不同的方法?

我只是想了解一下autofac,并希望有一个干净的方法来实现这一点。如果有一种简单的方法来枚举所有Foo类型(而不创建它们),并使用类型+运行时Id作为我的密钥,我可以只使用具体的Foo类型,而不是元数据。

使用有效的解决方案更新了代码。了解了如何使用元数据正确注册工厂。似乎有效。

最新更新