我在容器中注册了一堆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>();
,我正朝着正确的方向前进吗?
答案 0 :(得分:4)
在这种情况下,元数据比命名更合适。
对于强类型变体,定义一个用于保存元数据的接口:
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<,>
类型来自.NET 4.有关在.NET 3.5中实现此功能的详细信息以及替代语法,请参阅Autofac wiki。
答案 1 :(得分:1)
如果服务名称对您的应用程序很重要,那么可能应将其建模到您的代码中。例如,您有TaskParameters
;也许你想要这样的东西:
public class Descriptor<T>
{
private readonly string _description;
private readonly Func<T> _create;
public Descriptor(string description, Func<T> create)
{
_description = description;
_create = create;
}
public string Description { get { return _description; } }
public T Create() { return _create(); }
}
然后您可以为您的类型注册描述符。然后你可以轻松打电话
var descriptors = container.Resolve<IEnumerable<Descriptor<TaskParameters>>>();
答案 2 :(得分:0)
我找不到任何解决方案而不是查询上下文:
var ctx = Container.Resolve<IComponentContext>();
var taskNames = ctx.ComponentRegistry.Registrations
.Select(c => c.Services.FirstOrDefault() as KeyedService)
.Where(s => s != null && s.ServiceType == typeof (TaskParameters))
.Select(s => s.ServiceKey).ToList();
似乎这种方法不会实例化也不会激活任何东西。