StructureMap中如何为单个接口注册两种实现类型并使用?
如何在StructureMap中注册并使用IPageManager的两种命名实现?
你之前写的注册代码是完全正确的,已经成功把PageManager和EnhancedPageManager以单例模式、带命名标识的方式注册到了StructureMap容器中。接下来在ValuesController里使用这两个实现,有几种常用且规范的方式:
1. 构造函数注入(推荐,符合依赖注入最佳实践)
这是最推荐的方式,它能明确控制器的依赖关系,方便后续的测试和维护,有两种子方式可选:
方式A:通过IInstanceFactory解析命名实例
注入StructureMap的IInstanceFactory接口,然后在构造函数中根据名称获取对应的实现:
public class ValuesController : Controller { private readonly IPageManager _standardPageManager; private readonly IPageManager _enhancedPageManager; public ValuesController(IInstanceFactory instanceFactory) { _standardPageManager = instanceFactory.GetInstance<IPageManager>("pageManager"); _enhancedPageManager = instanceFactory.GetInstance<IPageManager>("enhancedPageManager"); } // 示例控制器方法 public IActionResult GetStandardPages() { var pages = _standardPageManager.GetPages(); return Ok(pages); } public IActionResult GetEnhancedPages() { var pages = _enhancedPageManager.GetPages(); return Ok(pages); } }
方式B:直接注入带命名标记的实例
使用StructureMap的[Named]特性标记构造函数参数,容器会自动匹配对应的命名实例完成注入:
public class ValuesController : Controller { private readonly IPageManager _standardPageManager; private readonly IPageManager _enhancedPageManager; public ValuesController( [Named("pageManager")] IPageManager standardPageManager, [Named("enhancedPageManager")] IPageManager enhancedPageManager) { _standardPageManager = standardPageManager; _enhancedPageManager = enhancedPageManager; } // 控制器业务方法... }
2. 属性注入(适用于特殊场景)
如果构造函数注入的方式对你的现有代码结构不太友好(比如不想修改已有构造函数),可以使用属性注入。需要确保StructureMap已启用属性注入(默认通常是开启状态),然后给属性添加[Named]标记:
public class ValuesController : Controller { [Named("pageManager")] public IPageManager StandardPageManager { get; set; } [Named("enhancedPageManager")] public IPageManager EnhancedPageManager { get; set; } public IActionResult SomeAction() { var standardPages = StandardPageManager.GetPages(); var enhancedPages = EnhancedPageManager.GetPages(); // 业务逻辑处理... return Ok(); } }
⚠️ 注意:属性注入会让依赖关系变得不明显,不利于测试和长期维护,所以优先选择构造函数注入。
3. 直接从容器解析(不推荐,避免服务定位器反模式)
如果在某些特殊场景下需要直接操作容器,可以通过IContainer实例获取命名实现,但这种方式会让代码耦合到容器,违反依赖注入的核心原则,不建议常规使用:
// 假设你能拿到StructureMap的IContainer实例 var container = ObjectFactory.Container; // 或者通过依赖注入获取IContainer var standardPageManager = container.GetInstance<IPageManager>("pageManager"); var enhancedPageManager = container.GetInstance<IPageManager>("enhancedPageManager");
内容的提问来源于stack exchange,提问作者mihkov
相关产品推荐
相关产品推荐

