Structuremap 3 单一接口多种类型

Structuremap 3 Single Interface Multiple Types

我有一个 ASP.NET MVC 5 应用程序,我使用 Structuremap 3 作为 IOC。

我有一个通过 N 层在多种类型中使用的接口,但我找不到关于如何将多种类型映射到同一接口以进行自动构造函数注入的简洁说明。

例如,我的注册表中有以下声明

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

当我 运行 我的应用程序时,我了解到最后添加的 IDataContextAsync 实例将是当我的应用程序创建需要 IDataContextAsync 作为构造函数中的参数的类型的实例时使用的默认实例。

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

谢谢。

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

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

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

为了告诉依赖者哪个实例应该传递给构造函数,您可以使用 Ctor 指令指定构造函数参数(参见文档 here):

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

这是一个容易混淆的 shorthand 名称:

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

或者,您可以跳过命名参数魔术,直接使用具体类型:

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