autofac:如何解决命名类型的集合?

iku*_*sin 7 c# autofac

我在容器中注册了一堆TaskParametes类实例,如:

builder.Register(c => [some type instantiation]
    )).Named<TaskParameters>("someTask").InstancePerDependency();

builder.Register(c => [some type instantiation]
    )).Named<TaskParameters>("someOtherTask").InstancePerDependency();
Run Code Online (Sandbox Code Playgroud)

这些类可以在应用程序的任何模块中注册.我想获取可用的命名实例列表以将其发送到客户端,客户端应该按名称实例化并执行它.

是否有选项可以获取名称列表,而无需实际实例化类型?目前我正在挖掘IComponentContext的ComponentRegistry,我得到了,var ctx = Container.Resolve<IComponentContext>();我是否朝着正确的方向前进?

Nic*_*rdt 4

在这种情况下,元数据比命名更合适。

对于强类型变体,定义一个接口来保存元数据:

public interface ITaskMetadata
{
    string Name { get; }
}
Run Code Online (Sandbox Code Playgroud)

然后在构建时关联元数据:

builder.Register(c => [some type instantiation]))
    .As<TaskParameters>()
    .WithMetadata<ITaskMetadata>(m =>
        m.For(tm => tm.Name, "someTask"));

builder.Register(c => [some type instantiation]))
    .As<TaskParameters>()
    .WithMetadata<ITaskMetadata>(m =>
        m.For(tm => tm.Name, "someOtherTask"));
Run Code Online (Sandbox Code Playgroud)

InstancePerDependency()被省略,因为它是默认行为。)

IEnumerable<Lazy<T,TMetadata>>然后,需要检查名称的组件可以像这样依赖:

class SomeComponent : ISomeComponent
{
    public SomeComponent(
        IEnumerable<Lazy<TaskParameters,ITaskMetadata>> parameters)
    {
        // Here the names can be examined without causing instantiation.
    }
}
Run Code Online (Sandbox Code Playgroud)

这使用关系类型来避免在容器中查找任何内容的需要。

请注意,该Lazy<,>类型来自 .NET 4。有关在 .NET 3.5 中实现此目的的详细信息以及替代语法,请参阅Autofac wiki