Autofac如何帮助您同时在现有类中注入类/接口的多个实例

问题描述 投票:-1回答:2

我是Autofac的新手,并不了解所有的潜力。我们来看一下网站文档中快速autofac教程中考虑的例子。 (https://autofac.readthedocs.io/en/latest/getting-started/index.html

using System;

namespace DemoApp
{

 public interface IOutput
 {
   void Write(string content);
 }

 public class ConsoleOutput : IOutput
 {
    public void Write(string content)
    {
        Console.WriteLine(content);
    }
  }

  public interface IDateWriter
  {
     void WriteDate();
  }

  public class TodayWriter : IDateWriter
  {
     private IOutput _output;
     public TodayWriter(IOutput output)
     {
         this._output = output;
     }

     public void WriteDate()
     {
         this._output.Write(DateTime.Today.ToShortDateString());
     }
 }
}

Autofac胶水看起来像这样:

using System;
using Autofac;

namespace DemoApp
{
   public class Program
   {
     private static IContainer Container { get; set; }

   static void Main(string[] args)
   {
       var builder = new ContainerBuilder();
       builder.RegisterType<ConsoleOutput>().As<IOutput>();
       builder.RegisterType<TodayWriter>().As<IDateWriter>();
       Container = builder.Build();

       WriteDate();
   }
  }
}


public static void WriteDate()
 {
  // Create the scope, resolve your IDateWriter,
  // use it, then dispose of the scope.
  using (var scope = Container.BeginLifetimeScope())
  {
    var writer = scope.Resolve<IDateWriter>();
    writer.WriteDate();
  }
}

该程序的目的只是在控制台上打印日期时间。假设我现在不仅要在控制台中打印日期时间,还要在日志中打印日期时间。为此,我想创建另一个具有接口IOutput的类,如下所示:

public class LogsOutput : IOutput
{
    public void Write(string content)
    {
        // write content to a log file here
    }
 }

这是一个纯粹的例子。我想将这个例子扩展到一个更大的问题。现在应该看起来像Autofac胶水代码?为了使代码执行ConsoleOutput classe和LogsOutput类并将输出打印到控制台和日志文件?

是否可以通过Autofac实现这一点,或者这不是autofac的行为?我可能希望能够使用IOutput接口添加数百个类。如何使用Autofac实现这一目标?

c# autofac ioc-container
2个回答
1
投票

创建一个新的IOutput类型后,

首先,您需要使用Named在容器中注册它:

var builder = new ContainerBuilder();
builder.RegisterType<ConsoleOutput>().Named<IOutput>("console");
builder.RegisterType<LogsOutput>().Named<IOutput>("logs");
builder.RegisterType<TodayWriter>().As<IDateWriter>();
Container = builder.Build();

然后,在WriteDate()方法中,通过使用Ioutput参数调用ResolveNamed方法来指定要使用的name的类型,该参数是在类型的注册中指定的名称:

public static void WriteDate()
 {
  // Create the scope, resolve your IDateWriter,
  // use it, then dispose of the scope.
  using (var scope = Container.BeginLifetimeScope())
  {
    var writer = scope.ResolveNamed<IDateWriter>("console"); // for console output
    //var writer = scope.ResolveNamed<IDateWriter>("logs"); // for logs output
    writer.WriteDate();
  }
}

注意:如果你不使用string名称,你可以使用与Keyeds一起使用的enumeration


0
投票

AutoFac通过依赖IEnumerable<T>直接支持这一点。当它看到IEnumerable时,它将返回满足接口T的所有注册类型的集合。

在你的情况下,将LogsOutputConsoleOutput注册为IOutput,并解决IEnumerable<IOutput>,以获得两个注册服务。


更多细节可以在here找到。

可枚举类型的依赖性提供相同服务(接口)的多个实现。这在诸如消息处理程序之类的情况下很有用,其中消息进入并且注册了多个处理程序来处理消息。

© www.soinside.com 2019 - 2024. All rights reserved.