当前位置:  开发笔记 > 编程语言 > 正文

Autofac可选/惰性依赖

如何解决《Autofac可选/惰性依赖》经验,为你挑选了1个好方法。

如果我把Lazy放在我的对象的构造函数中,并且X没有在容器中注册,我得到了依赖项解析异常.

为什么我得到这个例外?我不喜欢它,因为我无法在运行时选择组件.用例示例:

class Controller
{
   public Controller(Lazy a, Lazy b) { /* (...) */ }

 Lazy a;
 Lazy 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 components) { /* (...) */ }

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

    }

}

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



1> Travis Illig..:

如果添加对Lazy组件的引用,则Autofac必须(基本上)知道如果要解决它,将创建将运行的内部函数,即使您没有解决它.

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

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

Autofac需要注册您要解决的所有内容.它不允许你动态注册 - 它必须是明确的.所以你想要做的事情将无法奏效(如你所见).

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

var builder = new ContainerBuilder();
if(someConfig)
{
  builder.RegisterType().As();
}
else
{
  builder.RegisterType().As();
}

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

public MyController(Lazy service)

您还可以使用其他选项,例如使用组件或键控服务的元数据.例如,您可以根据配置添加一些元数据并使用它进行解析.

builder.RegisterType()
       .As()
       .WithMetadata("Name", "a");
builder.RegisterType()
       .As()
       .WithMetadata("Name", "b");

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

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

这是一个非常简短的例子,但文档显示了更多.

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

推荐阅读
mobiledu2402852357
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有