如何注册具有依赖项的 Autofac "Adapter"?

How do I register an Autofac "Adapter" that has dependencies?

Autofac 提供 RegisterAdapter,一种包装(或 adapt)实现的简单方法:

builder.RegisterAdapter<Meta<ICommand>, ToolbarButton>(
    cmd => new ToolbarButton(cmd.Value, (string)cmd.Metadata["Name"]));

这很酷,但是如果我的适配器构造函数需要 DI 支持怎么办?假设我的 ToolbarButton 构造函数如下所示:

public ToolbarButton(ICommand cmd, IService1 svc1, IService2 svc2) { ... }

而且我只想将我的 ToolbarButton 集合作为一个组合注入,所以我不需要元数据:

public Toolbar(IEnumerable<ToolbarButton> buttons) { ... }

所以我正在寻找注册我的 ICommand 适配器的最佳方式。 似乎我应该能够做这样的事情,让 Autofac 为它创建的每个适配器解析依赖服务:

builder.RegisterAdapter<ICommand, ToolbarButton>();

但是 RegisterAdapter() 没有这样的签名。 (为什么?)

所以我不得不做这样的事情,这似乎有点反模式和冗余:

builder.RegisterAdapter<ICommand, ToolbarButton>((ctx, from) =>
    new ToolbarButton(from, ctx.Resolve<IService2>(), ctx.Resolve<IService2>()));

或者如果我不想列出我的每个依赖项,我可以将 ICommand 作为参数传递:

builder.RegisterAdapter<ICommand, ToolbarButton>((ctx, from) =>
    ctx.Resolve<ToolbarButton>(new TypedParameter(typeof(ICommand), from)));

这也很丑陋,再一次,感觉就像我在告诉 Autofac 它应该已经知道的东西。有没有更好的方法?

感觉很难看,但仅此而已。如果它是一个装饰器而不是一个适配器,你会得到更多的“免费魔法”,但由于适配器可能需要更复杂的设置(它并不总是只是构造函数参数),现在提供的就是你所发现的:你必须在工厂函数中完成工作。

如果您对不同的行为有想法,可以随时open an issue提出您的建议。