ASP.Net Core中的依赖注入

时间:2018-09-18 13:52:38

标签: c# asp.net-core dependency-injection

曾经使用ASP.NET Core编写一些示例代码来尝试了解它们如何组合在一起,而我为无法成功解决服务的原因感到困惑。

configure services方法可以调用添加ISeedDataService

public void ConfigureServices(IServiceCollection services)
{
    services.AddOptions();
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

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

    services.AddScoped<ICustomerDbContext, CustomerDbContext>();
    services.AddScoped<ICustomerRepository, CustomerRepository>();
    services.AddScoped<ISeedDataService, SeedDataService>();
}

在“配置”中,我按如下所示调用AddSeedData()

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
   app.AddSeedData();
}

正在调用下面的扩展方法

public static async void AddSeedData(this IApplicationBuilder app)
{
    var seedDataService = app.ApplicationServices.GetRequiredService<ISeedDataService>();
    await seedDataService.EnsureSeedData();
}

并且SeedDataService在下面

public class SeedDataService : ISeedDataService
{
    private ICustomerDbContext _context;
    public SeedDataService(ICustomerDbContext context)
    {
        _context = context;
    }

    public async Task EnsureSeedData()
    {
        _context.Database.EnsureCreated();

        _context.Customers.RemoveRange(_context.Customers);
        _context.SaveChanges();

        Customer customer = new Customer();
        customer.FirstName = "Chuck";
        customer.LastName = "Norris";
        customer.Age = 30;
        customer.Id = Guid.NewGuid();

        _context.Add(customer);

        Customer customer2 = new Customer();
        customer2.FirstName = "Fabian";
        customer2.LastName = "Gosebrink";
        customer2.Age = 31;
        customer2.Id = Guid.NewGuid();

        _context.Add(customer2);

        await _context.SaveChangesAsync();
    }
}

完全不确定我在做什么,错误是 System.InvalidOperationException:'无法从根提供程序解析作用域服务'secondapp.Services.ISeedDataService'。

2 个答案:

答案 0 :(得分:2)

您正在(并且应该)将ISeedDataService添加为范围服务。但是,您正在尝试从不受限制的根服务提供商(例如app.ApplicationServices)来解决此问题。这意味着从中有效解析的范围服务将变成单例服务,并且直到应用程序关闭或将导致错误时才处置。

这里的解决方案是自己创建一个范围:

public void Configure(IApplicationBuilder app)
{
    using (var scope = app.ApplicationServices.CreateScope())
    {
        var seedDataService = scope.ServiceProvider.GetRequiredService<ISeedDataService>();
        // Use seedDataService here
    }
}

请查看at the documentation有关依赖项注入范围的信息。


第二点注意:您的AddSeedData扩展方法是async void,您不必等待结果。您应该返回一个调用async Task的任务(AddSeedData().GetAwaiter().GetResult()),以确保阻塞直到播种完成。

答案 1 :(得分:-1)

Configure()方法允许参数依赖注入,因此您可以执行以下操作。

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ISeedDataService seedService)
{
    seedService.EnsureSeedData().Wait(); // Configure() is not async so you have to wait
}