且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何在Identity ASP.NET Core 2.1(Identity Scaffolded)中为用户角色添加种子

更新时间:2023-02-25 08:33:21

您不能在Web主机 builder 上执行数据播种,因为当时尚未构建服务提供商.取而代之的是,您必须先实际创建Web主机,然后才能解析之前注册的任何服务.

You cannot perform data seeding on the web host builder since at that time, the service provider has not been built yet. Instead, you will have to actually create the web host first before you can resolve any services you have registered before.

我通常的建议是在创建WebHost之后在Program.cs中执行初始播种.按照默认模板,我将调整Main方法,使其看起来像这样:

My usual recommendation is to perform the initial seeding in the Program.cs after the WebHost is created. Following the default template, I would adjust the Main method to look like this:

public static async Task Main(string[] args)
{
    var host = CreateWebHostBuilder(args).Build();

    using (var scope = host.Services.CreateScope())
    {
        var roleManager = scope.ServiceProvider.GetService<RoleManager<MyWebRole>>();

        if (!await roleManager.RoleExistsAsync("admin"))
            await roleManager.CreateAsync(new MyWebRole { Name = "admin" });
    }

    await host.RunAsync();
}

因此,这将首先创建Web主机,然后将创建依赖项注入作用域,从该作用域将解析RoleManager实例.然后,您可以使用该经理来创建所需的角色.

So this will first create the web host, then it will create a dependency injection scope from which it will resolve a RoleManager instance. Using that manager you then can create the roles you require.

您还可以为此创建一个单独的服务,因此您不需要在Program.cs中包含所有逻辑,而可以依靠其他服务来执行数据播种:

You could also create a separate service for this, so you do not need to have all that logic inside the Program.cs but can just rely on some other service to perform the data seeding:

public static async Task Main(string[] args)
{
    var host = CreateWebHostBuilder(args).Build();

    using (var scope = host.Services.CreateScope())
    {
        var dataSeeder = scope.ServiceProvider.GetService<DataSeeder>();
        await dataSeeder.EnsureSeedDataAsync();
    }

    await host.RunAsync();
}

DataSeeder然后将在依赖项注入容器中注册.然后可以将RoleManager和其他服务(例如选项,甚至数据库上下文)作为依赖项,并在EnsureSeedDataAsync方法中执行播种.

The DataSeeder would then be registered with the dependency injection container. And then it could take the RoleManager and other services (e.g. options, or even the database context) as a dependency and perform the seeding in the EnsureSeedDataAsync method.

一种替代方法是使用实体框架核心数据种子功能,使用模型构建器上的.HasData()方法调用.但是,这需要在角色对象上使用固定的ID,并且您还必须在数据库级别创建对象,而不是依赖于更高级别的RoleManager.

An alternative would be to use the Entity Framework Core data seeding functionality using the .HasData() method call on the model builder. This however requires fixed IDs on your role objects and you will also have to create the objects at database level instead of relying on the higher-level RoleManager.