c# - 是否可以在 autofac 中使用某种动态 KeyFilter?
问题描述
Autofac 中使用的 KeyFilter 很有帮助,但实际上我认为它不是动态的,因为这里的键是预设/设置/定义的,并在编译时附加到构造函数参数。没有办法让类似的东西在运行时工作。
这是场景,在解决某些实例时,可以确定密钥(可以根据当前上下文动态更改)。然后在解析实例之前应考虑该密钥。我认为Multitenant
autofac 支持的功能非常接近该要求。但是我不认为它可以很容易地使用并支持构造函数注入(我们可能必须始终显式地手动创建范围和解析实例,这看起来很像服务定位器的方式)。
所以在代码版本选择示例中应用了这个虚构的特性,让我们看看它有多大帮助。假设我对同一个接口有 2 个实现,每个对应一个代码版本(v1 和 v2)。现在使用该接口的构造函数并不关心哪个版本,但上下文将为 IoC 容器提供哪个版本,以便它应该解析对应于该版本的正确实现。
public interface ISender {
void Send(string msg);
}
//version v1
public class SlowSender : ISender {
//...
}
//version v2
public class FastSender : ISender {
//...
}
现在是消费者类:
public class MyConsumer {
readonly ISender _sender;
public MyConsumer(ISender sender){
_sender = sender;
}
//do whatever with what ISender provides
}
因此,在这里解析 for 时MyConsumer
,autofac 应该知道要为我选择哪个版本,例如通过一些上下文信息提供程序,如下所示:
public class ContextInfoProvider : IContextInfoProvider //just an example
{
public string GetCurrentVersion(){
//can return some value picked from HttpContext.Current.Request
//or any ambient variable that can be injected at some very early time.
}
}
这是一种服务(非常快速的服务),可以帮助 autofac 知道在实例解析过程中应该考虑哪些(作为输入、参数)。
我知道这是可能的,但 autofac 可能尚未实现。实在是太可惜了。对于 autofac 支持的当前功能,您有任何替代解决方案吗?请注意,我不想使用类似服务定位器的代码,有时我们必须以这种方式使用它,但几乎在我们需要构造函数依赖注入的方式时,它只是简洁明了。
解决方案
您可以注册一个 lambda。将工厂逻辑放在那个 lambda 中。
builder.Register(ctx =>
var version = ctx.Resolve<IContextInfoProvider>().GetVersion();
if(version == 1)
{
return new SlowSender();
}
return new FastSender();
).As<ISender>();
推荐阅读
- node.js - 如何从 Autodesk Forge 获取 node.js axios 中的缩略图
- android - 错误:无法解决:androidx.recycleview:recyclerview:1.0.0
- python - PYTHON3 字典 - 为什么第一个答案不正确,而第二个答案是正确的
- vue-tables-2 - Vuetable-2:在实现复选框时,仅在第一个标题行中显示复选框
- groovy - 在 Groovy 中使用 XML 命名空间和 XmlSlurper - 如何正确查询路径?
- sql - SQL:如何选择值等于千的行(1列可能包含多个值)
- java - 滚动时列表视图项目未锁定
- sql - 如何使用 sql/knexjs 查询迭代 json 数据
- node.js - 如何更新已发布包的依赖项
- command - 是否有任何命令可以使用 adb 在 android 的文件管理器中启动目录?