是否可以在 autofac 中使用某种动态 KeyFilter?
Is it possible to have some kind of dynamic KeyFilter in autofac?
Autofac 中使用的 KeyFilter 很有用,但实际上我认为它不是动态的,因为这里的键是 preset/setup/defined 并在编译时附加到构造函数参数。没有办法让类似的东西在运行时工作。
场景如下,在解析某个实例时,可以确定密钥(可以根据当前上下文动态更改)。然后在解析实例之前应该考虑该密钥。我认为 autofac 支持的 Multitenant
功能非常接近该要求。但是我不认为它可以很容易地使用并且支持构造函数注入(我们可能必须始终创建一个范围并显式地手动解析实例,这看起来很像服务定位器的方式)。
所以在代码版本选择示例中应用了这个虚构的功能,让我们看看它有多大帮助。假设我对同一个接口有 2 个实现,每个对应一个代码版本(v1 和 v2)。现在使用该接口的构造函数不关心哪个版本,但上下文将提供 IoC 容器哪个版本,以便它应该解析对应于该版本的正确实现。
public interface ISender {
void Send(string msg);
}
//version v1
public class SlowSender : ISender {
//...
}
//version v2
public class FastSender : ISender {
//...
}
现在的消费者 class:
public class MyConsumer {
readonly ISender _sender;
public MyConsumer(ISender sender){
_sender = sender;
}
//do whatever with what ISender provides
}
所以在这里解析 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>();
Autofac 中使用的 KeyFilter 很有用,但实际上我认为它不是动态的,因为这里的键是 preset/setup/defined 并在编译时附加到构造函数参数。没有办法让类似的东西在运行时工作。
场景如下,在解析某个实例时,可以确定密钥(可以根据当前上下文动态更改)。然后在解析实例之前应该考虑该密钥。我认为 autofac 支持的 Multitenant
功能非常接近该要求。但是我不认为它可以很容易地使用并且支持构造函数注入(我们可能必须始终创建一个范围并显式地手动解析实例,这看起来很像服务定位器的方式)。
所以在代码版本选择示例中应用了这个虚构的功能,让我们看看它有多大帮助。假设我对同一个接口有 2 个实现,每个对应一个代码版本(v1 和 v2)。现在使用该接口的构造函数不关心哪个版本,但上下文将提供 IoC 容器哪个版本,以便它应该解析对应于该版本的正确实现。
public interface ISender {
void Send(string msg);
}
//version v1
public class SlowSender : ISender {
//...
}
//version v2
public class FastSender : ISender {
//...
}
现在的消费者 class:
public class MyConsumer {
readonly ISender _sender;
public MyConsumer(ISender sender){
_sender = sender;
}
//do whatever with what ISender provides
}
所以在这里解析 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>();