Autofac:如何在同一接口上注册多个类型以与装饰器一起使用?

时间:2019-02-21 22:38:05

标签: dependency-injection autofac

我没有看到如何在与装饰器一起使用的同一接口上注册和解析类型。为了解决装饰器以及ILogger和IConfiguration的相同实例,我这样声明它们:

builder.RegisterType<FluentFtpFileHandler>().Named<IFileHandler>("fileHandler");
builder.RegisterType<LocalFileHandler>().Named<IFileHandler>("fileHandler");
builder.RegisterDecorator<IFileHandler>((c, inner) =>
    new LogDecorator(inner.Logger, inner.Configuration, inner), fromKey: "fileHandler");

在工厂课堂上,我该如何解决e。 G。 FluentFtpFileHandler的实例?

1 个答案:

答案 0 :(得分:1)

当您注册实现同一接口的多种类型时,以胜利为准。

builder.RegisterType<FluentFtpFileHandler>().As<IFileHandler>();
builder.RegisterType<LocalFileHandler>().As<IFileHandler>();
var container = builder.Build();
var handler = container.Resolve<IFileHandler>();
// handler is going to be LocalFileHandler
// because LAST IN WINS.

如果您需要在不同情况下解析不同的处理程序,则这有点代码味道,因为您实际上无法将所有处理程序都视为相同。 There's an FAQ on that举例说明了为什么不是那么好,但也提供了一些解决方法的想法。

回到装饰器的情况,我建议尝试使用the new decorator syntax,因为它比传统语法更容易混淆。

builder.RegisterType<FluentFtpFileHandler>().Named<IFileHandler>("ftpHandler");
builder.RegisterType<LocalFileHandler>().Named<IFileHandler>("localHandler");
builder.RegisterDecorator<LogDecoerator, IFileHandler>();
var container = builder.Build();
var handler = container.ResolveNamed<IFileHandler>("ftpHandler");
// Handler should be a decorated instance of the FTP handler.

我正在通过我的“非常确定这应该可行”的心理编译器来运行此程序,因此,如果语法没有从字面上复制/粘贴到该位置,我对此感到抱歉。