我在容器中注册了一堆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>();我是否朝着正确的方向前进?
在这种情况下,元数据比命名更合适。
对于强类型变体,定义一个接口来保存元数据:
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。