AutoFac / .NET Core - зарегистрировать DBcontext - PullRequest
0 голосов
/ 02 мая 2018

У меня есть новый проект .NET Core Web API, который имеет следующую структуру проектов:

API -> Бизнес / Домен -> Инфраструктура

API очень тонкий, только с API-методами. Уровень Business / Domain имеет всю мою бизнес-логику. И наконец, на моем уровне инфраструктуры есть классы БД, использующие EF Core 2.0.

Я знаю, что с помощью встроенного в .NET Core Inpendency Injection я могу добавить ссылку из проекта API в проект инфраструктуры, а затем добавить следующий код в файл StartUp.cs:

services.AddDbContext<MyContext>(options => options.UseSqlServer(connectionString));

Однако я бы хотел придерживаться более традиционного разделения интересов. До сих пор я добавил модуль в свой слой инфраструктуры, который пытается сделать регистрацию следующим образом:

builder.Register(c =>
        {
            var config = c.Resolve<IConfiguration>();

            var opt = new DbContextOptionsBuilder<MyContext>();
            opt.UseSqlServer(config.GetSection("ConnectionStrings:MyConnection:ConnectionString").Value);

            return new MyContext(opt.Options);
        }).AsImplementedInterfaces().InstancePerLifetimeScope();

DBContext, однако, не регистрируется. Любой класс, который пытается получить доступ к внедренному DBContext, не может разрешить параметр.

Есть ли способ зарегистрировать DBContext в отдельном проекте, используя AuftoFac в проекте .NET Core Web API?

Ответы [ 4 ]

0 голосов
/ 19 декабря 2018

Еще одно простое решение для Autofac версии 4.8.1

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc().AddControllersAsServices();

        services.AddDbContext<MyContext>(options => options.UseSqlServer(Configuration.GetConnectionString("ConnectionStrings:MyConnection:ConnectionString")));

        var builder = new ContainerBuilder();

        builder.Populate(services);

        //...
        // Your interface registration
        //...

        builder.Build(Autofac.Builder.ContainerBuildOptions.None);
    }
0 голосов
/ 02 мая 2018

Я думаю, что проблема в том, что вы пытаетесь зарегистрировать MyContext(), используя AsImplementedInterfaces(). Обычно DbContext регистрируется не так. Вы должны зарегистрироваться и разрешить сам класс.

0 голосов
/ 03 сентября 2018

Я использую Autofac для регистрации HttpContextAccessor и DbContext.

builder.RegisterType<HttpContextAccessor>().As<IHttpContextAccessor>().SingleInstance();

builder
    .RegisterType<AppDbContext>()
    .WithParameter("options", DbContextOptionsFactory.Get())
    .InstancePerLifetimeScope();

DbContextOptionsFactory

public class DbContextOptionsFactory
{
    public static DbContextOptions<AppDbContext> Get()
    {
        var configuration = AppConfigurations.Get(WebContentDirectoryFinder.CalculateContentRootFolder());

        var builder = new DbContextOptionsBuilder<AppDbContext>();
        DbContextConfigurer.Configure(builder, configuration.GetConnectionString(AppConsts.ConnectionStringName));

        return builder.Options;
    }
}

DbContextConfigurer

public class DbContextConfigurer
{
    public static void Configure(DbContextOptionsBuilder<AppDbContext> builder, string connectionString)
    {
        builder.UseNpgsql(connectionString).UseLazyLoadingProxies();
    }
}
0 голосов
/ 02 мая 2018

В желаемом проекте вы можете создать метод расширения, который добавляет контекст в коллекцию

public static class MyDataExtensions {
    public static IServiceCollection AddMyData(this IServiceCollection services) {
        //...

        services.AddDbContext<MyContext>(options => options.UseSqlServer(connectionString));

        //...
    }
}

с этим, тогда в вашем запуске это просто вопрос вызова расширения, выставленного из другого проекта

services.AddMyData();

//...other settings

Проект API - это корень композиции, поэтому в любом случае ему необходимо знать все соответствующие зависимости. По крайней мере, с этим расширением вам не нужно делать прямую ссылку на используемый контекст БД,

...