Используйте DI на уровне доступа к данным с ApplicationDbContext (netcore 2.0)

У меня проблема с DI (Dependancy Injection). Мой проект находится на netcore 2.0 и имеет несколько слоев (стандартная архитектура N-Tier). Я пытаюсь переместить EF Core 2 из Presentation Layer в Data Access Layer, и я создал следующие классы в DAL:

namespace MyProject.Infrastructure.Implementation.MySql.Contexts 
{
    public class ApplicationDbContext : DbContext
    {
        private readonly IConfiguration _configuration;

        public ApplicationDbContext(IConfiguration configuration)
        {
            _configuration = configuration;
        }

        protected override void OnConfiguring(DbContextOptionsBuilder     optionsBuilder)
        {
            optionsBuilder.UseMySql(
                Configuration.GetConnectionString("MySql")
            );
        }

        public DbSet<Test> Test { get; set; }
    }
}

Затем я подготовил базовый класс для всех двигателей DAL:

namespace MyProject.Infrastructure.Implementation.MySql
{
    public class BaseEngine : IBaseEngine
    {
        private readonly ApplicationDbContext _context;

        protected ApplicationDbContext Db => _context;

        public BaseEngine(ApplicationDbContext context)
        {
            _context = context;
        }
    }
}

Итак, мой общий движок должен выглядеть так:

namespace MyProject.Infrastructure.Implementation.MySql
{
    public class TestEngine : BaseEngine
    {
        public List<Test> GetTestList()
        {   
            return Db.Test.ToList();
        }
    }
}

Проблема в том, что я получаю сообщение об ошибке, BaseEngine требует передачи параметра в конструктор, и я не хочу создавать все экземпляры вручную, мне нужно каким-то образом использовать Dependancy Injection, который автоматически создает экземпляры ApplicationDbContext и IConfiguration, когда будут созданы BaseEngine и ApplicationDbContext.

Любые идеи?


person Arkadi    schedule 12.02.2018    source источник


Ответы (1)


Создайте общедоступный интерфейс для ApplicationDbContext, например IApplicationDbContext. Поместите это в конструктор для BaseEngine вместо конкретного класса. Сделайте конструктор BaseEngine защищенным. Конструктор BaseEngine должен выглядеть так:

protected BaseEngine(IApplicationDbContext context)

Затем, поскольку TestEngine является производным от BaseEngine, а BaseEngine требует аргумента конструктора, вы должны передать его из конструктора TestEngine, например:

public TestEngine(IApplicationDbContext context) : base(context)
person Joe Wilson    schedule 12.02.2018