曾经使用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'。
答案 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
}