【问题标题】:Using Autofac as a service locator使用 Autofac 作为服务定位器
【发布时间】:2011-11-03 16:24:22
【问题描述】:

我正在使用 Autofac 来处理我的应用程序中的依赖注入。但是,我有一个组件可以在运行时执行一些反射魔法,但在编译时我不知道它需要什么依赖项。

通常,我会让这个组件直接引用容器并解析它想要的任何东西。但是,实例化这个类的类没有对 Container 的引用。

实际上,我的组件依赖于 Autofac。我更喜欢更松散的耦合,但这似乎不是一个选择。有没有办法询问(在构造函数参数中,或使用属性注入,或其他任何东西!)Autofac 给我在构造函数中对容器的引用?或者,有没有更简洁的方法让 Autofac 为我提供可以解决任何问题的神奇服务定位器对象?

【问题讨论】:

  • 看看组件在做什么“魔法”会很有趣。也许除了服务定位器模式之外还有其他方法。你能更新一些代码吗?
  • 我可以很好地描述它。当消息通过总线进入时,代码使用一些元数据确定消息的类型,然后构造所述类型。然后它需要使用 Autofac 找到 IConsume<type> 的所有实现者(其中 type 是元数据中的类型),然后对其调用 Consume 方法。
  • 你的意思是:kozmic.pl/2010/03/11/…
  • 是的,但很少有转化为 Autofac。

标签: c# dependency-injection inversion-of-control autofac


【解决方案1】:

是的,你可以。只需依赖IComponentContext

public class MyComponent
{
    IComponentContext _context;
    public MyComponent(IComponentContext context)
    {
        _context = context;
    }

    public void DoStuff()
    {
        var service = _context.Resolve(...);
    }
}

来自 cmets 的更新:注入 MyComponentIComponentContext 取决于解析 MyComponent 的范围。因此,重要的是要考虑注册了MyComponent 的生命周期范围。例如。使用InstancePerLifetimeScope,上下文将始终解析为依赖于MyComponent 的服务所在的同一范围。

【讨论】:

  • 这是否适用于多个生命周期范围?即 IComponentContext 是基础容器还是作用域?
  • 它将从解析MyComponent 的范围解析IComponentContext。因此,如果MyComponent 注册为InstancePerLifetimeScopecontext 将始终从预期范围解析。
【解决方案2】:

假设您有两个组件,A 和 B。

如果 A 在使用 B 之前需要了解 X,这就是元数据询问,在 excellent 帖子中有描述。

此外,即使您的设计无法适应该帖子,您也应该再次尝试确定您是否真的需要将 DI 容器用作服务定位器。

在撰写本文时,我能找到的描述它的最佳博客文章是this one。

【讨论】:

  • 我不知道你为什么要用与我的问题完全无关的东西来回答一个已经得到很好回答的问题......正如我所说,我的问题是不知道哪个“ B" 我需要解决直到运行时。
  • @NikosBaxevanis +1,即使 OP 似乎没有得到它。两个帖子都很棒。 Nicholas 帖子中的这句话概括了这一切:“同时,几乎没有任何借口可以再在您的组件中使用 IContainer 或 IComponentContext 了”。
【解决方案3】:

在其他情况下,当您的组件不是使用 DI 创建时,您仍然可以使用服务定位器模式。 CodePlex 上的 Common Service Locator 库非常适合此目的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-08-06
    • 2018-06-15
    • 1970-01-01
    • 2017-12-08
    • 2018-06-23
    • 2012-02-25
    • 2012-10-20
    • 1970-01-01
    相关资源
    最近更新 更多