#c# #asp.net-core #dependency-injection #entity-framework-core #simple-injector
#c# #asp.net-ядро #внедрение зависимостей #сущность-фреймворк-ядро #простой инжектор
Вопрос:
Я настраиваю ASP.NET Основной проект и следование шаблону CQRS, основанному на моей работе над проектом Tripod. Я следовал руководству по интеграции простого инжектора, но немного озадачен одним моментом… Я хочу продолжать использовать UseInMemoryDatabase
опцию для тестирования и могу найти примеры этого только с использованием метода Core DI AddDbContext
.
Мой DbContext реализует несколько интерфейсов:
public class EntityDbContext : DbContext,
IUnitOfWork,
IReadEntities,
IWriteEntities
{
// code here
}
Я делаю это в Startup.ConfigureServices
методе:
services.AddDbContext<EntityDbContext>(options => options.UseInMemoryDatabase("Snoogans"));
и следуя руководству по интеграции SI, это при запуске.Метод настройки:
container.Register<IUnitOfWork, xxxx>();
container.Register<IReadEntities, xxxx>();
container.Register<IWriteEntities, xxxx>();
Могу ли я получить регистрацию ядра через crosswire для подключения к цели для каждого из них или я должен просто регистрировать контекст непосредственно в 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);
Ответ №1:
Могу ли я получить регистрацию ядра через crosswire для подключения к цели для каждого из них или я должен просто регистрировать контекст непосредственно в SI?
Возможны оба варианта. Вы можете зарегистрировать DbContext непосредственно в Simple Injector. Обычно это наиболее очевидный выбор, поскольку ваш DbContext является компонентом приложения. Компоненты приложения обычно должны регистрироваться в вашем контейнере приложения (т.Е. Simple Injector), а не в системе регистрации фреймворка (т.Е. ServiceCollection
).
Однако, когда дело доходит до регистрации DbContext
, существует некоторая тесная интеграция с ASP.NET Система конфигурации ядра. Это может упростить регистрацию там и просто выполнить перекрестное подключение из простого инжектора. Это позволяет системе конфигурации сохранять контроль над созданием и уничтожением DbContext. Это становится особенно ценным при выполнении таких действий, как объединение DbContext, поскольку эта функциональность объединения тесно связана с этим конфигурационным и регистрационным API.
Обычно оба варианта довольно просты, но поскольку ваш DbContext реализует несколько интерфейсов, которые вы хотите зарегистрировать отдельно, это усложняет вашу регистрацию. Это также имело бы место в случае, если вы также используете встроенный контейнер DI, так что это не относится конкретно к 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);
В случае, если вы решили подключить свой DbContext из системы конфигурации .NET Core, ваша конфигурация будет выглядеть следующим образом:
// 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);
Если бы вы использовали не простой инжектор, а исключительно встроенный DI-контейнер .NET Core, регистрация выглядела бы следующим образом:
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>());