c# - Autofac。检索所有注册为命名的服务

标签 c# .net inversion-of-control autofac ioc-container

我正在尝试在程序中使用命名注册。但是文档中的示例不起作用。 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 >>();

返回一个空列表

更新

部分问题已经解决。在实验过程中,我创建了一些名称相似的接口(interface)。结果,我注册了一个接口(interface),但解决了其他接口(interface)。

现在这条线可以工作了:

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

但是,我无法获得实现该接口(interface)的类的完整列表:

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(接口(interface)),但 SimpleService1 仅注册为类(因为命名注册),而不是接口(interface)。

试试这个:

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

关于c# - Autofac。检索所有注册为命名的服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34810466/

相关文章:

c# - wp 8.1 页面导航时的奇怪行为

c# - ML.NET 算法评估有关乳腺癌的实例总是错误的

dependency-injection - 使用 Ninject 2.0 注入(inject)多个相同类型的构造函数参数

c# - 在 Ninject 中寻找通用接口(interface)的具体实现

c# - 使用正则表达式提取所有内容,直到特定符号重复出现

c# - Spring.NET 等效于 Java Spring 数据访问用法

c# - 如何创建正确的 InstanceDescriptor 来初始化一些属性

.net - System.Reactive 5.0 中缺少 DispatcherScheduler

c# - 解决 Unity 中的依赖关系

c# - 关于在 C# 中将运算符作为 ENUM 中的值的问题