从Core 2迁移到Core 2.1时,将DbContext作为DI

时间:2018-07-07 15:53:40

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

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

Startup.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();
    }
}

1 个答案:

答案 0 :(得分:1)

.Net Core的2.1版本只是向您揭示了您在迁移之前所持有的错误。由于以下原因,您的课程AdRepository被作为一个单例实例注入:

services.AddSingleton<IAdRepository, AdRepository>();

但是同一类依赖于上下文类RealEstatesContext,该上下文类默认情况下已注入并确定范围,这意味着每个HTTP请求将具有其自己的RealEstatesContext类实例。

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

要解决此问题,只需确保将AdRepository注入如下范围:

services.AddScoped<IAdRepository, AdRepository>();

代替

services.AddSingleton<IAdRepository, AdRepository>();