首页 > 解决方案 > 如何注册具有依赖关系的 Autofac“适配器”?

问题描述

Autofac 提供了RegisterAdapter,这是一种包装(或适配)实现的简单方法:

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 它应该已经知道的东西。有没有更好的办法?

标签: c#adapterautofac

解决方案


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

如果您对不同的行为有想法,您可以随时针对您的提案提出问题


推荐阅读