AutoFac / .NET Core-зарегистрировать DBcontext
у меня есть новый проект .NET Core Web API, который имеет следующую структуру проектов:
API - > бизнес / домен - > инфраструктура
API очень тонкий только с методами API. Уровень Business / Domain имеет всю мою бизнес-логику. И, наконец, мой уровень инфраструктуры имеет мои классы БД, использующие EF Core 2.0.
Я знаю, используя встроенную инъекцию зависимостей .NET Core, я могу добавить ссылку из проекта API в проект инфраструктуры, а затем добавьте следующий код при запуске.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?
3 ответов
Я думаю, что проблема в том, что вы пытаетесь зарегистрироваться MyContext()
используя AsImplementedInterfaces()
. Обычно DbContext регистрируется не так. Вы должны зарегистрировать и разрешить сам класс.
Я использую 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();
}
}
в нужном проекте вы можете создать метод расширения, который добавляет контекст в коллекцию
public static class MyDataExtensions {
public static IServiceCollection AddMyData(this IServiceCollection services) {
//...
services.AddDbContext<MyContext>(options => options.UseSqlServer(connectionString));
//...
}
}
С этим тогда в вашем запуске это просто вопрос вызова расширения, выставленного из другого проекта
services.AddMyData();
//...other settings
проект API является корнем композиции, поэтому он должен знать все соответствующие зависимости в любом случае. По крайней мере, с этим расширением вам не нужно делать прямую ссылку на используемый контекст БД,