c# - Autofac 可选/惰性依赖项

标签 c# autofac lazy-initialization

如果我将 Lazy 放入对象的构造函数中,并且 X 未在容器中注册,我会遇到依赖项解析异常。

为什么我会收到此异常?我不喜欢它,因为我不能在运行时选择组件。示例用例:

class Controller
{
   public Controller(Lazy<A> a, Lazy<B> b) { /* (...) */ }

 Lazy<A> a;
 Lazy<B> b;

 public IActionResult Get(){
  if(someConfig)
    return Json(a.Value.Execute());
  else
    return Json(b.Value.Execute());
 }
}

为此,我需要注册组件 A 和 B。即使从未使用过 B,我的程序也会失败。我希望 B 是可选的,并且仍然由 autofac 管理。

如果我有组件列表,并且只想使用一个组件,这会是一个更大的问题。例如:

class Controller
{
    Controller(IEnumerable<Component> components) { /* (...) */ }

    IActionResult Get()
    {
        return components.First(n => n.Name == configuredComponent).Execute();

    }

}

我不再遇到未注册的异常,但仍然构建了所有内容。使用起来也很尴尬。

最佳答案

如果您添加对 Lazy<T> 的引用组件,Autofac 必须(基本上)知道如何创建将运行的内部函数,如果您想解析它,即使您解析它也是如此。 p>

基本上,它需要能够在内存中创建:

var lazy = new Lazy<T>(() => scope.Resolve<T>());

Autofac 要求注册您要解决的所有问题。它不允许您动态注册东西——它必须是明确的。所以您尝试做的事情不会起作用(如您所见)。

相反,使用一个接口(interface)和该接口(interface)的两个不同实现。根据您的配置值更改注册。

var builder = new ContainerBuilder();
if(someConfig)
{
  builder.RegisterType<A>().As<IService>();
}
else
{
  builder.RegisterType<B>().As<IService>();
}

然后在您的 Controller 中,注入(inject)接口(interface)而不是具体类。

public MyController(Lazy<IService> service)

您还可以使用其他选项,例如使用 metadata用于组件或 keyed services .例如,您可以根据您的配置添加一些元数据并使用它进行解析。

builder.RegisterType<A>()
       .As<IService>()
       .WithMetadata("Name", "a");
builder.RegisterType<B>()
       .As<IService>()
       .WithMetadata("Name", "b");

在 Controller 中,你会得到它们的字典:

public MyController(IEnumerable<Meta<IService>> services)
{
  var service = services.First(s => s.Metadata["Name"].Equals(someConfig);
}

这是一个非常简短的示例,但是 the docs show a lot more .

无论如何,界面确实是您成功的关键。如果您只是使用具体类,则无论您是否使用它们都必须注册。

关于c# - Autofac 可选/惰性依赖项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41856560/

相关文章:

c# - VS2013 代码分析自定义字典不工作

asp.net-core - FluentValidation 装饰器不适用于 autofac 和 mediator

c# - autofac:如何解析命名类型的集合?

java - JPA/Hibernate Spring @Transactional 与 JOIN FETCH

c# - 除了需要为我的测试方法工作外,没有其他验证

c# - 无论我输入什么数字,我的文本框总是与 '0' 进行比较

c# - 在 C# 中从 Base64 解码

c# - 获取成员拦截的属性值

java - 无法在此 ManagedType 上找到具有给定名称 [trackers] 的属性

java - Hibernate 延迟加载、代理和继承