简体   繁体   English

将多个EF上下文注册到DI容器中

[英]Register multiple EF contexts into a DI container

I'm starting to develop an application using Domain Driven Design concepts and applying n-layer patterns for the architecture. 我开始使用域驱动设计概念开发应用程序并为架构应用n层模式。 My problem is related to this question : because I need to create one or more database contexts. 我的问题与这个问题有关 :因为我需要创建一个或多个数据库上下文。

Instead of to instantiate my contexts using the new keyword, I'm using Ninject to create a DI container and resolve all dependencies automatically, but here starts the confusion! 我没有使用new关键字实例化我的上下文,而是使用Ninject创建一个DI容器并自动解决所有依赖关系,但这里开始混乱!

This is basically what I have here: 这基本上就是我在这里:

public interface IDataContext : IDisposable 
{ 
}

public abstract class DataContext : DbContext, IDataContext 
{
}

public class ContextA : DataContext
{
}

public class ContextB : DataContext
{
}

The first question is how to register the contexts, when they are implementing the same interface? 第一个问题是如何在实现相同的接口时注册上下文?

And the second question is how should to call the repositories, eg: 第二个问题是如何调用存储库,例如:

public class MyClass(IUserRepository userRepository, IBankRepository bankRepository)
{
  // IUserRepository is inside ContextA
  // IBankRepository is inside ContextB
}

In the sample code above, I'd like to use the same UnitOfWork. 在上面的示例代码中,我想使用相同的UnitOfWork。 Is that possible? 那可能吗?

The first question is how to register the contexts, when they are implementing the same interface? 第一个问题是如何在实现相同的接口时注册上下文?

This is where your problem is. 这就是你的问题所在。 According to the Liskov Substitution Principle implementations of an abstraction should be interchangable without causing the consumer to break. 根据Liskov替换原则 ,抽象的实现应该是可互换的,而不会导致消费者破坏。 Since each DbContext will have its own model, a consumer will typically expect one particular data model and will break (at runtime) when you supply it with a different model. 由于每个DbContext都有自己的模型,因此消费者通常会期望一个特定的数据模型,并在您为其提供不同的模型时中断(在运行时)。

And this violation directly causes you trouble with registration. 而这种违规直接导致您注册时遇到麻烦。 So the solution is to give each context its own abstraction and register those abstractions separately. 因此,解决方案是为每个上下文提供自己的抽象,并分别注册这些抽象。

If you have users in ContextA and banks in ContextB you should reflect it in your interfaces so the repository is constructed with the context containing the expected entities : 如果ContextA中有用户,ContextB中有银行,则应在接口中反映它,以便使用包含预期实体的上下文构建存储库:

public interface IDataContext : IDisposable 
{ 
}

public interface IContextA : IDataContext
{
   public DbSet<User> Users { get; set; } 
}

public interface IContextB : IDataContext
{
   public DbSet<Bank> Banks { get; set; } 
}

public abstract class DataContext : DbContext, IDataContext 
{
}

public class ContextA : DataContext, IContextA
{
}

public class ContextB : DataContext, IContextB
{
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM