StructureMap使用每个命名空间的特定类型实例

时间:2014-04-02 14:42:53

标签: c# asp.net dependency-injection inversion-of-control structuremap

有没有办法,使用StructureMap(依赖注入容器)将类型的特定实例注入到请求该类型的给定命名空间的所有类型中?

以下是设置示例:

EmployeesDbContext : IAbstractDbContext { ... }
AccountingDbContext : IAbstractDbContext { ... }
MarketingDbContext : IAbstractDbContext { ... }

StructureMap按照预期在IAbstractDbContext中注册所有这些类型。

然后:

  • HumanResources.Domain,其中包含与Employees数据库相关的业务逻辑和实体,因此需要EmployeesDbContext
  • Accounting.Domain,其具有与Accounting数据库相关的业务逻辑和实体,因此需要AccountingDbContext
  • 等...

然后我有一个WebUI(ASP.NET MVC)项目,它可以被认为是组合根,它利用了构成依赖树的StructureMap。

最有意义的是利用DbContext需求主要由使用它的命名空间驱动的事实。

麻烦的是,我不确定如何解决这个问题,任何想法都非常感激!

2 个答案:

答案 0 :(得分:1)

当您有一个抽象IAbstractDbContext时,它意味着所有实现都是可互换的。但是,您很可能无法交换它们,因为一些消费者希望使用Employees数据模型,而其他人则期望使用Marketing模型。因此,您违反了Liskov substitution principle

相反,您应该为每个模型定义一个抽象。例如:IEmployeesDbContextIAccountingDbContextIMarketingDbContext。这样做可以解决导致您遇到麻烦的设计模糊问题。这使得更容易理解消费者需要什么样的数据模型,并允许您简化注册过程,因为您不再需要任何有条件注册。

答案 1 :(得分:1)

如我的评论中所述,史蒂文的答案可能是正确的。

据我所知,根据消费者的命名空间,不能直接解决依赖关系。但是,您可以使用命名实例和反射到达那里。我建议采用这种方法 - 最好创建显式命名实例并直接通过工厂解析它们。

简而言之:

  • 按名称空间
  • 注册IAbstractDbContext的命名实例
  • 使用一种方法创建一个IDbContextFactory类:IAbstractDBContext Create(string namespace)。让实现包装容器实例并通过字符串参数解析。
  • 在使用类的构造函数中注入工厂
  • 使用reflect来获取使用者类的名称空间,然后使用工厂创建DbContext实例,将名称空间作为参数传递。