C# 使用DbContext层次结构重用ASP.NET控制器和服务

C# 使用DbContext层次结构重用ASP.NET控制器和服务,c#,asp.net-mvc,asp.net-core,dependency-injection,entity-framework-core,C#,Asp.net Mvc,Asp.net Core,Dependency Injection,Entity Framework Core,使用ASP.NET MVC和.NET Core 2.2 我有几个类似的数据库,并且具有DbContext的层次结构,例如: public class BaseContext : DbContext {} public class DerivedContext : BaseContext {} 我的服务和控制器应与DbContext一起工作: public class MyService { public MyService(BaseContext dbContext) {} } pub

使用ASP.NET MVC和.NET Core 2.2

我有几个类似的数据库,并且具有DbContext的层次结构,例如:

public class BaseContext : DbContext {}
public class DerivedContext : BaseContext {}
我的服务和控制器应与DbContext一起工作:

public class MyService
{
    public MyService(BaseContext dbContext) {}
}
public class MyController : ControllerBase
{
    public MyController (BaseContext dbContext) {}
}
我尝试将其用于派生数据库,如下所示:

services.AddDbContext<DerivedContext>(x => ...);
services.AddDbContext(x=>…);

问题在于依赖项注入器无法解析BaseContext参数。如何在依赖项注入容器中注册派生类型,并在请求基类型时提供它?

这对于依赖项注入者来说是不可能的,他需要一个具体的唯一类型或接口,可以解析为特定的服务。 对于服务,您可以使用泛型类型来设置服务实例使用的上下文类型。但这也需要您为每种上下文注册一次服务,并且您必须在每个控制器中区分您想要使用哪种服务

如果您有相似的数据库,为什么不为这两个数据库重用上下文。这两种语境有什么区别


对于您来说,在同一上下文中有多个配置不同的实例可能会很有趣。这可能是最好、最干净的方法,因为控制器和服务在上下文之间没有任何差异。我还使用此行为处理具有多个方案的数据库,这些方案包含完全相同的表。例如,可以手动将
DeriverContext
注册为
BaseContext

services.AddDbContext<DerivedContext>(x => ...);
services.AddScoped<BaseContext>(c => c.GetRequiredService<DerivedContext>());
services.AddDbContext(x=>…);
services.addScope(c=>c.GetRequiredService());
这类似于代理的工作方式


您还可以编写扩展方法来封装上下文注册。

尝试改用接口IBaseContext。。不确定这是否有效。@Marlon我相信你可以做到,但我不希望这样,因为这只是镜像BaseContext公共接口的额外代码。除了解决这个问题外,它没有任何用处。数据库并不完全相同。其中一个有一些附加表和修改的SaveChanges实现。