首页 > 解决方案 > 从 Core 2 迁移到 Core 2.1 时将 DbContext 作为 DI

问题描述

我正在使用 .Net Core 2 并且一切正常,但是在我创建基于 .Net Core 2.1 角度的应用程序后,我得到了运行时错误:Cannot consume scoped service 'RealEstate.Data.RealEstatesContext' from singleton 'RealEstate.Repositories.DI.IAdRepository'.我知道由于范围差异而发生错误。但是我如何将 DI 与 Dbcontext 一起使用。

启动.cs

public void ConfigureServices(IServiceCollection services)
{
        services.AddDbContext<RealEstatesContext>(options =>
            options.UseSqlServer(Configuration.GetConnectionString("RealEstatesContext"))
        ); 
        services.AddScoped<GetAdHandler>();
        services.AddSingleton<IAdRepository, AdRepository>();
}

GetAdHandler.cs

public class GetAdHandler
{
    private readonly IAdRepository _adRepository;

    public GetAdHandler(IAdRepository adRepository) 
    {
        _adRepository = adRepository;
    }

    protected override async Task<BaseResponse<AdDto>> HandleAsync(GetRequest<int> request) 
    {
        AdDto ad = await _adRepository.GetAdAsync(request.Id);
        return new BaseResponse<AdDto> {
            Result = ad
        };
    }
}

AdRepository.cs

public class AdRepository : IAdRepository 
{
    private readonly RealEstatesContext _context;

    public AdRepository(RealEstatesContext context) 
    {
        _context = context;
    }

    public async Task<List<AdCardDto>> GetAdsAsync() 
    {
        _context.Ads.ToListAsync();
    }
}

标签: c#asp.net-core-2.0ef-core-2.0asp.net-core-2.1ef-core-2.1

解决方案


.Net Core 2.1 版只是向您揭示了您在迁移之前遇到的一个错误。由于以下原因,您的类AdRepository被注入为单例实例:

services.AddSingleton<IAdRepository, AdRepository>();

但是同一个类依赖于您的上下文类RealEstatesContext,该类默认情况下被注入和限定范围,这意味着每个 HTTP 请求都有自己的RealEstatesContext类实例。

所以想象一下有很多用户在使用你的应用程序。每个用户的请求都将被分配给一个与其他用户不同的特定 HTTP 请求。因此,在您的应用程序中,每个 HTTP 请求都将共享相同的AdRepository(所有请求的单个实例),但其他用户可能会处理RealEstatesContext可能由另一个用户的 HTTP 请求实例化的实例。只有许多用户同时使用您的应用程序才能看到这种错误。

因此,要解决它,只需确保注入您的AdRepositoryas 范围,如下所示:

services.AddScoped<IAdRepository, AdRepository>();

代替

services.AddSingleton<IAdRepository, AdRepository>();

推荐阅读