簡體   English   中英

autofac:如何解決命名類型的集合?

[英]autofac: How to resolve collection of named types?

我在容器中注冊了一堆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.
    }
}

這使用關系類型來避免在容器中查找任何內容。

注意, Lazy<,>類型來自.NET 4.有關在.NET 3.5中實現此功能的詳細信息以及替代語法,請參閱Autofac wiki

如果服務名稱對您的應用程序很重要,那么可能應該將其建模到您的代碼中。 例如,您有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>>>();

我找不到任何解決方案而不是查詢上下文:

    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();

似乎這種方法不會實例化也不會激活任何東西。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM