如何注册具有依赖项的 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提出您的建议。
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提出您的建议。