ASP.NET Core DI с простым совместным использованием инжектора DbContext - PullRequest
1 голос
/ 18 марта 2019

Я настраиваю проект ASP.NET Core и следую шаблону CQRS, основываясь на моей работе над проектом Штатив . Я следовал руководству по интеграции Simple Injector, но немного озадачен одним моментом ... Я хочу продолжать использовать опцию UseInMemoryDatabase для тестирования и могу найти только примеры этого с использованием метода Core DI AddDbContext.

Мой DbContext реализует несколько интерфейсов:

public class EntityDbContext : DbContext,
    IUnitOfWork,
    IReadEntities,
    IWriteEntities
{
    // code here
}

Я делаю это в Startup.ConfigureServices методе:

services.AddDbContext<EntityDbContext>(options => options.UseInMemoryDatabase("Snoogans"));

и следуйте указаниям по интеграции с SI в методе Startup.Configure:

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);

1 Ответ

3 голосов
/ 19 марта 2019

Могу ли я получить регистрацию Ядра по перекрестному соединению, чтобы подключить к цели для каждого из них, или мне просто нужно зарегистрировать контекст непосредственно в 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);

В случае, если вы решили подключить свой 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);

Если вы не захотитене использовать Simple Injector, а только встроенный 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>());
...