I'm very new to Autofac and don't understand still all the potential. Let's take the example considered in the quick autofac tutorial in the website documentation. (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());
}
}
}
And the Autofac glue looks like this:
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();
}
}
The purpose of this program is simply to print the datetime on the console. Suppose now that I want to print the datetime not only in the console but also in the logs. For this purpose i want to create another class having interface IOutput like this:
public class LogsOutput : IOutput
{
public void Write(string content)
{
// write content to a log file here
}
}
This is a pure example. I want to extend this example to a bigger problem. Now how should look like the Autofac glue code ? in order for the code to execute both ConsoleOutput classe and LogsOutput class and to print the output to both the console and the log file ?
Is it possible to achieve this with Autofac or is this not in the behaviour of autofac ? I possibly want to ba able to add hundreds of classes all with the IOutput interface. How to achieve this with Autofac ?
答案 0 :(得分: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
的名称,则可以使用Keyed来使用enumeration
的名称。
答案 1 :(得分:0)
AutoFac通过依赖IEnumerable<T>
直接支持此功能。看到IEnumerable
时,它将返回满足接口T
的所有已注册类型的集合。
在您的情况下,都注册LogsOutput
,并将ConsoleOutput
注册为IOutput
,并解析IEnumerable<IOutput>
,以获取两个注册服务。
更多详细信息,请参见here。
可枚举类型的依赖项提供了多种实现 相同的服务(接口)。这在诸如消息之类的情况下很有用 处理程序,其中有一条消息传入,并且有多个处理程序是 注册以处理该消息。