Как внедрить DbContext в конструктор репозитория в ядре ASP.NET - PullRequest
1 голос
/ 30 мая 2019

Я пишу свой первый ASP.NET Core Web API и пытаюсь понять, как внедрить мой объект DbContext в конструктор репозитория.Я следовал части EF этого учебника , где DbContext регистрируется в коллекции сервисов через services.AddDbContext<DbContext>, а services.GetRequiredService<DbContext>() используется для инициализации значений базы данных.

    public class Startup
    {

        public IConfiguration Configuration { 

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
            services.AddSingleton<IItemRepository, ItemRepository>();
            services.AddSingleton<IUserRepository, UserRepository>();

            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new Info { Title = "My API", Version = "v1" });
            });

            services.AddDbContext<RAFYCContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

        }
    }
    public class Program
    {
        public static void Main(string[] args)
        {
            //CreateWebHostBuilder(args).Build().Run();

            IWebHost host = CreateWebHostBuilder(args).Build();

            using (IServiceScope scope = host.Services.CreateScope())
            {
                IServiceProvider services = scope.ServiceProvider;
                try
                {
                    RAFYCContext context = services.GetRequiredService<RAFYCContext>();
                    DbInitializer.Initialize(context);
                }
                catch (Exception ex)
                {
                    ILogger logger = services.GetRequiredService<ILogger<Program>>();
                    logger.LogError(ex, "An error occurred while seeding the database.");
                }
            }

            host.Run();
        }
    }

Я могу вставить DbContext в контроллер и затем вызвать метод репозитория, чтобы назначить его в репозиторий UserRepository:

    public class UserController : ControllerBase
    {
        IUserRepository _userRepo;

        public UserController(IUserRepository userRepo, RAFYCContext context)
        {
            _userRepo = userRepo;
            _userRepo.SetDbContext(context);
        }
    }
    public class UserRepository : IUserRepository
    {
        public RAFYCContext _context;

        public UserRepository() { }

        public void SetDbContext(RAFYCContext context)
        {
            this._context = context;
        }
    }

Это работает, однако я хотел бы добавить DbContext в конструктормоего репозитория вместо назначения его в конструкторе Controller после создания экземпляра, как показано ниже:

    [Route("api/[controller]")]
    [ApiController]
    public class UserController : ControllerBase
    {
        IUserRepository _userRepo;

        public UserController(IUserRepository userRepo)
        {
            _userRepo = userRepo;
        }
    }
    public class UserRepository : IUserRepository
    {
        RAFYCContext _context;

        public UserRepository(RAFYCContext context)
        {
            _context = context;
        }
    }

С этим кодом я получаю следующую ошибку:

InvalidOperationException: Cannotиспользовать сервис RAFYC.MobileAppService.Models.RAFYCContext из синглтона RAFYC.MobileAppService.Repositories.IUserRepository '

Кто-нибудь знает, возможно ли это с помощью ASP.NET Core (2.2)?

1 Ответ

1 голос
/ 30 мая 2019

AddDbContext добавляет DbContext в качестве области по умолчанию, что может вызвать проблемы с одноэлементными репозиториями.

Опасно разрешать службу с заданной областью из одного объекта.Это может привести к неправильному состоянию службы при обработке последующих запросов.

Ссылка Внедрение зависимостей в ASP.NET Core: время жизни службы

Я бы предложил добавитьрепозитории, если это возможно, также ограничены.

services.AddScoped<IItemRepository, ItemRepository>();
services.AddScoped<IUserRepository, UserRepository>();
...