2011-08-25 56 views
13

我正在使用Autofac在我的应用程序中处理依赖注入。然而,我有一个组件在运行时做了一些反射魔术,我不知道它在编译时需要什么依赖。使用Autofac作为服务定位器

通常情况下,我只想让这个组件直接引用Container并解决它想要的任何内容。但是,实例化此类的类没有对容器的引用。

实际上,我的组件依赖于Autofac。我宁愿松散耦合,但在这里似乎不是一种选择。有没有办法(在构造函数的参数,或使用属性注入,或任何!)Autofac给我在我的构造函数容器的引用?或者,有没有更好的方法让Autofac为我提供一个可以解决任何问题的魔术服务定位器对象?

+2

虽然看到组件正在做什么“魔术”,但会很有趣。也许除了服务定位器模式之外,还有其他方法。你能用一些代码更新吗? –

+0

我可以很好地描述它。随着消息通过总线进入,代码确定消息使用某些元数据的类型,然后构造所述类型。然后它需要使用Autofac查找所有'IConsume '的实现者(其中'type'是来自元数据的类型),然后调用它的Consume方法。 –

+0

你的意思是:http://kozmic.pl/2010/03/11/advanced-castle-windsor-ndash-generic-typed-factories-auto-release-and-more/ –

回答

12

是的,你可以。只要采取的依赖上IComponentContext

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

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

更新来自点评:IComponentContext注入MyComponent取决于从哪个MyComponent得到解决的范围。因此,重要的是要考虑注册了什么样的终身范围MyComponent。例如。使用InstancePerLifetimeScope,上下文将始终解析到取决于MyComponent的服务所处的相同范围。

+0

这将使用多个生命周期范围吗?即IComponentContext是基础容器还是范围? –

+3

它将解析'MyComponent'被解析的范围中的'IComponentContext'。所以如果'MyComponent'被注册为'InstancePerLifetimeScope','context'将始终从预期的范围中解析出来。 –

+0

完美,正是我所需要的。 –

1

假如你有两个组件,A和B.

如果A需要使用它之前了解关于B X,这是元数据的审讯,并在此excellent职位描述。

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

在写这篇文章的时候,我能找到的最好的博客文章是this之一。

+0

我不确定为什么你会回答一个已经回答良好的问题,而这个问题根本与我的问题无关......正如我所说,我的问题是不知道我需要解决哪个“B”问题直到运行时。 –

+1

@NikosBaxevanis +1,即使OP似乎没有得到它。这两个帖子都很棒。Nicholas发布的这个单词恢复了这一切:“同时,在你的组件中几乎没有任何借口可以使用IContainer或IComponentContext”。 – rsenna

0

在其他情况下,如果您的组件不是通过使用DI创建的,您仍然可以使用服务定位器模式。 CodePlex上的通用服务定位器库是完美的。