简体   繁体   English

使用Autofac作为服务定位器

[英]Using Autofac as a service locator

I'm using Autofac to handle dependency injection in my application. 我正在使用Autofac来处理我的应用程序中的依赖注入。 However, I have one component that does some reflection magic at runtime and I don't know at compile-time what dependencies it will need. 但是,我有一个组件在运行时执行一些反射魔法,我不知道它在编译时需要什么依赖项。

Ordinarily, I would just have this component reference the Container directly and resolve whatever it wants. 通常,我只是让这个组件直接引用Container并解决它想要的任何问题。 However, the class that is instantiating this class has no reference to the Container. 但是,实例化此类的类没有对Container的引用。

Effectively, my component has a dependency on Autofac. 实际上,我的组件依赖于Autofac。 I'd prefer looser coupling, but that doesn't seem to be an option here. 我更喜欢松散耦合,但这似乎不是一个选择。 Is there a way to ask (in the constructor args, or using property injection, or whatever!) Autofac to give me a reference to the container in my constructor? 有没有办法问(在构造函数args中,或使用属性注入,或其他什么!)Autofac给我一个对我的构造函数中的容器的引用? Or, is there a cleaner way to have Autofac provide me with a magic service locator object that can resolve anything? 或者,是否有一种更简洁的方法让Autofac为我提供可以解决任何问题的魔术服务定位器对象?

Yes, you can. 是的你可以。 Just take a dependency on the IComponentContext : 只需依赖IComponentContext

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

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

Update from the comments: the IComponentContext injected into MyComponent depends on the scope from which MyComponent was resolved. 从注释更新:注入MyComponentIComponentContext取决于MyComponent解析范围。 It is thus important to consider with what lifetime scope MyComponent is registered. 因此,重要的是要考虑MyComponent生命周期范围。 Eg using InstancePerLifetimeScope , the context will always resolve to the same scope in which the service depending on MyComponent lives. 例如,使用InstancePerLifetimeScope ,上下文将始终解析为依赖于MyComponent的服务所在的相同范围。

Supposing you have two components, A and B. 假设你有两个组件,A和B.

If A needs to know X about B before using it, this is Metadata interrogation and it is described in this excellent post. 如果A在使用它之前需要知道关于B的X,那么这就是元数据询问,并在这篇优秀文章中进行了描述。

Furthermore, even if you can't adapt your design to that post, you should again try to make sure if you really need to use your DI Container as a Service Locator. 此外,即使您无法使您的设计适应该帖子,您也应该再次尝试确保是否确实需要将DI容器用作服务定位器。

At the time of this writting, the best blog post I could find describing it is this one. 在撰写本文时,我能找到的最好的博客文章就是这篇文章

In other cases, when your component is not created by using DI, you still can use the service locator pattern. 在其他情况下,如果未使用DI创建组件,则仍可以使用服务定位器模式。 The Common Service Locator library on CodePlex is perfect for the purpose. CodePlex上的Common Service Locator库非常适合此目的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM