2015-12-02 73 views
0

我有一个ASP.NET MVC 5应用程序,我使用Structuremap 3作为IOC。Structuremap 3单接口多种类型

我有一个通过N层使用多种类型的接口,我无法找到如何将多种类型映射到自动构造函数注入的相同接口的简洁说明。

比如我在注册表中的以下声明

For<IDataContextAsync>().Use<DbGeoContext>(); 
For<IDataContextAsync>().Use<DbEspContext>(); 

当我跑我的应用我理解IDataContextAsync的最后添加的实例将使用的默认实例时,我的应用程序创建一个类的实例需要一个IDataContextAsync作为构造函数中的参数。

所以我的问题是我如何告诉Structuremap 3在注册表中使用与正在创建的类型相关的IDataContextAsync的特定实例?

谢谢。

回答

0

为了区分不同的实现,可以使用命名实例(请参阅文档here)。您注册一个命名实例是这样的:

//Default instance 
For<IDataContextAsync>().Use<DbGeoContext>(); 
For<IDataContextAsync>().Add<DbEspContext>().Named("EspContext"); 

注意,Add方法,无需将其设置为默认注册了一个实例,而Use方法它注册为默认实例。正如您已经意识到的那样,使用Use方法注册的最后一个实例成为默认实例。

为了判断哪些实例应该传递给构造一个dependee,您可以使用Ctor指令指定构造函数的参数(见文档here):

For<IMyRepository>().Use<MyRepository>() 
    .Ctor<IDataContextAsync>().Named("EspContext"); 

这是一个容易混淆的命名简写:

For<IMyRepository>().Use<MyRepository>() 
    .Ctor<IDataContextAsync>() 
    .Is(c => c.GetInstance<IDataContextAsync>("EspContext")); 

或者,你可以跳过指定的参数魔法,只是直行的具体类型有:

For<IMyRepository>().Use<MyRepository>() 
    .Ctor<IDataContextAsync>().Is<DbEspContext>(); 
+0

嗨,谢谢你的回复,最终我发现了它,但是我花了一段时间。我会标记你的答案,但我还没有足够的分数。 – Csharper

+0

其实我在应用程序启动时发现了一个问题,我检索EspContext的实例并更新它的连接字符串,但是当我将请求追踪到存储库层时,连接字符串没有改变?嗯...是否有另一种方法比GetInstance将做同样的事情,但没有创建一个实例? – Csharper

+0

从一开始就将连接字符串设置为正确的值不是更容易吗?如果直到应用程序生命周期中的某个特定时间点才知道该值,请使用工厂模式并注入一个可生成连接的工厂,而不是注入实际连接。我认为你的问题是,它与你更改的版本库不同。您可以为结构图中的每种类型设置[生命周期](http://structuremap.github.io/object-lifecycle/supported-lifecycles/)。默认值为transient(每个对象图的新对象)。 – PHeiberg