c# - ASP.NET Core DI 与 Simple Injector 共享 DbContext
问题描述
我正在建立一个 ASP.NET Core 项目,并根据我在Tripod项目上的工作遵循 CQRS 模式。我遵循了 Simple Injector 集成指南,但在某一点上有点困惑......我想继续使用该UseInMemoryDatabase
选项进行测试,并且只能找到使用 Core DIAddDbContext
方法的示例。
我的 DbContext 实现了几个接口:
public class EntityDbContext : DbContext,
IUnitOfWork,
IReadEntities,
IWriteEntities
{
// code here
}
我在Startup.ConfigureServices
方法中这样做:
services.AddDbContext<EntityDbContext>(options => options.UseInMemoryDatabase("Snoogans"));
并在 Startup.Configure 方法中遵循 SI 集成指南:
container.Register<IUnitOfWork, xxxx>();
container.Register<IReadEntities, xxxx>();
container.Register<IWriteEntities, xxxx>();
我是否能够通过交叉线将核心注册到每个目标的插件,还是应该直接在 SI 中注册上下文?
== 我正在玩 Tripod 的原始概念:
var contextRegistration =
lifestyle.CreateRegistration<EntityDbContext, EntityDbContext>(container);
container.AddRegistration(typeof(EntityDbContext), contextRegistration);
container.AddRegistration(typeof(IUnitOfWork), contextRegistration);
container.AddRegistration(typeof(IWriteEntities), contextRegistration);
container.AddRegistration(typeof(IReadEntities), contextRegistration);
试图用 SI 做所有事情,但不确定我如何获得 3 个接口的注册:
container.Register<EntityDbContext>(() =>
{
var optionsBuilder =
new DbContextOptionsBuilder<EntityDbContext>().UseInMemoryDatabase("Snoogans");
return new EntityDbContext(optionsBuilder.Options);
});
container.AddRegistration<IUnitOfWork>(xxxx);
container.AddRegistration<IReadEntities>(xxxx);
container.AddRegistration<IWriteEntities>(xxxx);
解决方案
我是否能够通过交叉线将核心注册到每个目标的插件,还是应该直接在 SI 中注册上下文?
两种选择都是可行的。您可以选择将 DbContext 直接注册到 Simple Injector 中。这通常是最明显的选择,因为您的 DbContext 是一个应用程序组件。应用程序组件通常应该在您的应用程序容器(即 Simple Injector)中注册,而不是在框架的注册系统(即ServiceCollection
)中。
然而,在注册DbContext
方面,与 ASP.NET Core 配置系统有一些紧密的集成。这可以更直接地在那里进行注册,并简单地从 Simple Injector 进行交叉接线。这让配置系统可以控制 DbContext 的创建和销毁。这在执行 DbContext 池之类的操作时变得特别有价值,因为此池功能与此配置和注册 API 紧密耦合。
通常,这两个选项都非常简单,但是因为您的 DbContext 实现了您想要单独注册的多个接口,这会导致您的注册变得更加复杂。如果您也使用内置的 DI 容器,情况也会如此,因此这并非特定于 Simple Injector。
在您的情况下,纯粹在 Simple Injector 中进行注册将如下所示:
var reg = Lifestyle.Scoped.CreateRegistration(() =>
{
var optionsBuilder =
new DbContextOptionsBuilder<EntityDbContext>().UseInMemoryDatabase("Snoogans");
return new EntityDbContext(optionsBuilder.Options);
},
container);
container.AddRegistration<IUnitOfWork>(reg);
container.AddRegistration<IReadEntities>(reg);
container.AddRegistration<IWriteEntities>(reg);
如果您选择从 .NET Core 配置系统交叉连接 DbContext,您的配置将如下所示:
// Add to the built-in ServiceCollection
services.AddDbContext<EntityDbContext>(options => options.UseInMemoryDatabase("Snoogans"));
// Cross-wire in Simple Injector
container.CrossWire<EntityDbContext>(app);
// Pull that registration out of Simple Injector and use it for the interface registrations
var reg = container.GetRegistration(typeof(EntityDbContext)).Registration;
// Same as before
container.AddRegistration<IUnitOfWork>(reg);
container.AddRegistration<IReadEntities>(reg);
container.AddRegistration<IWriteEntities>(reg);
如果您不使用 Simple Injector,而是纯粹使用 .NET Core 的内置 DI 容器,则注册将如下所示:
services.AddDbContext<EntityDbContext>(options => options.UseInMemoryDatabase("Snoogans"));
services.AddScoped<IUnitOfWork>(c => c.GetRequiredService<EntityDbContext>());
services.AddScoped<IReadEntities>(c => c.GetRequiredService<EntityDbContext>());
services.AddScoped<IWriteEntities>(c => c.GetRequiredService<EntityDbContext>());
推荐阅读
- c++ - OpenCV 读取 RGB 值。每次运行的值都不一致
- android - 在没有应用更新的情况下在移动设备上更新 Tensor Flow Lite 模型?
- netbeans - Netbeans:是否可以使用 CLI 创建项目
- ember.js - setupController 不适用于 hasMany 数据
- json - Openlayers - 调用 json 文件时获取 404
- testing - 如何在 Flutter 集成测试中切换开关
- c - 如何获取用户输入以在 C 中打开文件?
- tensorflow - 当我处理超过 1.5 Gig CSV 时,张量流数据验证在 4 核机器上崩溃
- python - 如何在pyspark中将字符串值转换为arrayType
- javafx - 场景构建器中的 Javafx 表视图未插入用户输入