在autofac中是否可以使用某种动态KeyFilter?

问题描述 投票:0回答:1

在Autofac中使用的KeyFilter很有帮助,但实际上我认为它不是动态的,因为此处的键是预置/设置/定义的,并在编译时附加到构造函数参数上。无法在运行时进行类似的操作。

这里是场景,在解决某些实例时,可以确定密钥(可以根据当前上下文动态更改密钥)。然后,在解决实例之前应考虑该密钥。我认为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 {
    //...
}

现在是消费者类:

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支持的当前功能?请注意,我不想使用类似service-locator的代码,有时我们必须那样使用,但是几乎在我们需要构造函数依赖注入的方式的时候,它只是干净整洁。

c# dynamic dependency-injection autofac constructor-injection
1个回答
0
投票

您可以注册一个lambda。将工厂逻辑放在该lambda中。

builder.Register(ctx =>
  var version = ctx.Resolve<IContextInfoProvider>().GetVersion();
  if(version == 1)
  {
    return new SlowSender();
  }
  return new FastSender();
).As<ISender>();
© www.soinside.com 2019 - 2024. All rights reserved.