我在容器中注册了一堆TaskParametes类实例,如:
builder.Register(c => [some type instantiation] )).Named<TaskParameters>("soMetask").InstancePerDependency(); builder.Register(c => [some type instantiation] )).Named<TaskParameters>("someOtherTask").InstancePerDependency();
这些类可以在应用程序的任何模块中注册.我想获取可用的命名实例列表以将其发送到客户端,客户端应该按名称实例化并执行它.
是否有选项可以获取名称列表,而无需实际实例化类型?
目前我正在挖掘IComponentContext的ComponentRegistry,我得到了它,var ctx = Container.Resolve< IComponentContext>();我正朝着正确的方向前进吗?
解决方法
在这种情况下,元数据比命名更合适.
对于强类型变体,定义用于保存元数据的接口:
public interface ITaskMetadata { string Name { get; } }
然后在构建时关联元数据:
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"));
(省略InstancePerDependency(),因为它是默认行为.)
然后,需要检查名称的组件可以依赖于IEnumerable< Lazy< T,TMetadata>>像这样:
class SomeComponent : ISomeComponent { public SomeComponent( IEnumerable<Lazy<TaskParameters,ITaskMetadata>> parameters) { // Here the names can be examined without causing instantiation. } }
这使用relationship types来避免在容器中查找任何内容.
注意,Lazy<,> type来自.NET 4.有关在.NET 3.5中实现此功能的详细信息以及替代语法,请参阅Autofac wiki.