簡體   English   中英

Autofac。 檢索注冊為已命名的所有服務

[英]Autofac. Retrieve all services registered as named

我正在嘗試在程序中使用命名注冊。 但是文檔中的示例不起作用。 http://autofac.readthedocs.org/en/latest/advanced/keyed-services.html#named-services

public class DbLoggerModule : Autofac.Module
{
protected override void Load(Autofac.ContainerBuilder builder)
{
builder.Register<DbLogger>().Named<ILogger>("1");
}

並得到編譯錯誤:方法'Register'的重載沒有接受0個參數

我還嘗試了以下變體:

builder.RegisterType<DbLogger>().Named<ILogger>("1");
builder.RegisterType<DbLogger>().Named<ILogger>("1").As<ILogger>();
builder.RegisterType<DbLogger>().Named<ILogger>("1").As<ILogger>();
builder.RegisterType<DbLogger>().As<ILogger>().Named<ILogger>("1");            

它們不會引起編譯錯誤。 但是由於並非不可能獲得給定的命名服務:

  1. var lll =_сontainer.ResolveNamed<ILogger>(“ 1”);

引發異常: 所請求的服務'1(Console1.ILogger)'未注冊。 為避免此異常,請注冊一個組件以提供服務,使用IsRegistered()檢查服務注冊,或使用ResolveOptional()方法解決可選的依賴項。

  1. IEnumerable記錄器=_сontainer.Resolve<IEnumerable <ILogger>>();

返回一個空列表

更新

部分問題已解決。 在實驗過程中,我創建了一些名稱相似的接口。 結果,我注冊了一個接口,但解決了另一個。

現在此行正在工作:

var lll = _сontainer.ResolveNamed< ILogger >("1");

但是,我無法獲得實現該接口的類的完整列表:

var lll = _сontainer.ResolveNamed<ILogger>("1");
lll.Log(null);   // working !
IEnumerable< ILogger >loggers=_сontainer.Resolve<IEnumerable< ILogger >>();// It returns an empty list

當我拒絕命名服務時,該程序開始工作:

builder.RegisterType<DbLogger>().As<ILogger>();
...
_сontainer.Resolve<IEnumerable<ILogger>>(); // working !

我懷疑我們無法獲得注冊為已命名服務的列表。 有人可以確認嗎?

更新2這是一個非常簡單但完整的示例。 這是行不通的。 為什么呢

public interface ISimpleService
{
    string Test();
}
public class SimpleService1 : ISimpleService
{
    public string Test()
    {
        return "Hello World from SimpleService1";
    }
}

internal class Program
{
    private static void Main(string[] args)
    {
        var builder = new ContainerBuilder();
        {
            builder.RegisterType<SimpleService1>().Named<ISimpleService>("fff");
        }

        IContainer container = builder.Build();

        var services = container.Resolve<IEnumerable<ISimpleService>>();

        Console.WriteLine(services.Count()); // 0. Why ?
    }
}

您試圖解析ISimpleService(接口),但是SimpleService1僅注冊為類(因為命名注冊),而不注冊為接口。

嘗試這個:

builder.RegisterType<SimpleService1>().Named<ISimpleService>("fff").As<ISimpleService>();

要么

builder.RegisterType<SimpleService1>().Named<ISimpleService>("fff").AsImplementedInterfaces();

一個完整的示例:

public interface ISimpleService
    {
        string Test();
    }
    public class SimpleService1 : ISimpleService
    {
        public string Test()
        {
            return "Hello World from SimpleService1";
        }
    }

    internal class Program
    {
        private static void Main(string[] args)
        {
            var builder = new ContainerBuilder();
            {
                builder.RegisterType<SimpleService1>().Named<ISimpleService>("fff").As<ISimpleService>();
            }

            IContainer container = builder.Build();

            var services = container.Resolve<IEnumerable<ISimpleService>>();

            Console.WriteLine(services.Count()); // 1.
        }
    }

如果按名稱解析ISimpleService,則初始示例將起作用:

var services = container.ResolveNamed<IEnumerable<ISimpleService>>("fff");

您的代碼應該可以工作。

您確定已在容器中注冊了模塊?

自舉容器(程序集掃描或簡單注冊)時,請確保如下所示:

// This example being fx a console app    
containerBuilder.RegisterAssemblyModules(Assembly.GetExecutingAssembly());

// Basic registration    
containerBuilder.RegisterModule<LoggerModule>();

// Ensure the container is build
_container = containerBuilder.Build();

如果您要解析一個已命名列表(只有那些,而不是那些已注冊名稱的列表,如其他答案所示),您可以執行以下操作:

builder.RegisterType<Foo>().Named<IFoo>("IFoo").SingleInstance();
builder.RegisterType<Foo2>().Named<IFoo>("IFoo").SingleInstance();
builder.RegisterType<Foo3>().Named<IFoo>("2").As<IFoo>().SingleInstance();

var container = builder.Build();

//Will resolve type Foo2
var foo = container.ResolveNamed<IFoo>("IFoo");

//Will resolve 2 IFoo: Foo and Foo2
var foos = container.ResolveNamed<IEnumerable<IFoo>>("IFoo");

暫無
暫無

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

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