簡體   English   中英

Autofac如何幫助您同時在一個現有類中注入一個類/接口的多個實例

[英]How Autofac helps You to inject multiple instances of a class/interface in an existing class at the same time

我對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類又可以執行LogsOutput類,並且可以將輸出打印到控制台和日志文件中?

是否可以使用Autofac實現此目的,或者這不是autofac的行為嗎? 我可能希望能夠通過IOutput接口添加數百個類。 如何使用Autofac實現這一目標?

創建新的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()方法中,通過使用帶有name參數的ResolveNamed方法(該類型的注冊中指定的名稱)來指定要使用的Ioutput類型:

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的名字,你可以使用鍵控與工作enumeration秒。

AutoFac通過依賴IEnumerable<T>直接支持此功能。 當看到IEnumerable ,它將返回滿足接口T的所有已注冊類型的集合。

在您的情況下,將LogsOutputConsoleOutput 注冊為IOutput ,並解析IEnumerable<IOutput>以獲得兩個已注冊的服務。


可以在此處找到更多詳細信息。

可枚舉類型的依賴關系提供同一服務(接口)的多種實現。 這在消息處理程序之類的情況下很有用,其中有一條消息進入,並且注冊了多個處理程序來處理該消息。

暫無
暫無

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

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