【问题标题】:Autofac optional/lazy dependenciesAutofac 可选/惰性依赖
【发布时间】:2017-01-25 16:21:00
【问题描述】:

如果我将 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();

    }

}

我不再收到异常是没有注册的东西,但是一切都被构建了。使用起来也很尴尬。

【问题讨论】:

    标签: c# autofac lazy-initialization


    【解决方案1】:

    如果您添加对 Lazy&lt;T&gt; 组件的引用,Autofac 必须(基本上)知道如何创建将运行的内部函数如果您想解决它,即使您 不要解决它。

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

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

    Autofac 要求您注册所有要解决的问题。它不允许您即时注册事物 - 它必须是明确的。因此,您尝试做的事情将行不通(如您所见)。

    改为使用单个接口和该接口的两个不同实现。根据您的配置值更改注册。

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

    然后在您的控制器中,注入接口而不是具体类。

    public MyController(Lazy<IService> service)
    

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

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

    在控制器中,您将获得它们的字典:

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-04-09
      • 2013-08-08
      • 2017-01-26
      • 2011-07-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多