结构映射使用每个命名空间类型的特定实例

本文关键字:类型 实例 命名空间 映射 结构 | 更新日期: 2023-09-27 17:56:07

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

下面是一个设置示例:

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

StructureMap 按预期针对 IAbstractDbContext 注册所有这些类型。

然后:

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

然后我有一个WebUI(ASP.NET MVC)项目,可以将其视为组合根,它利用StructureMap来组成依赖树。

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

麻烦的是,我不确定如何处理这个设置,任何想法都非常感谢!

结构映射使用每个命名空间类型的特定实例

当你有一个抽象IAbstractDbContext时,这意味着所有实现都是可互换的。但是,您不太可能交换它们,因为一些使用者希望使用"员工"数据模型,而另一些使用者希望使用"营销"模型。因此,您违反了利斯科夫替换原则。

相反,您应该为每个模型定义一个抽象。例如:IEmployeesDbContextIAccountingDbContextIMarketingDbContext。这样做可以解决设计中给您带来麻烦的歧义。这使得理解使用者需要什么数据模型变得更加容易,并允许您简化注册过程,因为您不再需要任何条件注册。

正如我在评论中指出的,史蒂文的回答可能是正确的。

据我所知,基于使用者的命名空间无法直接解决依赖项。 但是,您可以使用命名实例和反射来实现目标。 我建议采用这种方法 - 最好创建显式命名实例并直接通过工厂解析到它们。

简而言之:

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