2016-10-08 2 views
16

В приложении ASP.NET Core я хочу создать определенные роли в качестве основы для управления различными правами пользователя. К сожалению, в документации сообщается о том, как использовать пользовательские роли, например. в контроллерах/действиях, но не в том, как их создавать. Я узнал, что для этого могу использовать RoleManager<IdentityRole>, где экземпляр автоматически вводится в конструктор-контроллер, когда его определение и идентификатор ядра ASP.NET регистрируются в приложении.Идентификатор ядра ASP.NET Добавление пользовательских ролей пользователя при запуске приложения

Это позволило мне добавить пользовательскую роль, как это:

var testRole = new IdentityRole("TestRole"); 
if(!roleManager.RoleExistsAsync(testRole.Name).Result) { 
    roleManager.CreateAsync(testRole); 
} 

Он работает и создание роли в базе данных. Но эта проверка всегда создает накладные расходы в базе данных, вызывая конкретный контроллер/действие. Поэтому я хочу проверить один раз после запуска моего приложения, если пользовательская роль существует и добавляет их. Метод ConfigureServices в Startup.cs кажется хорошим для этого.

Но: Как я могу создать экземпляр класса RoleManager<IdentityRole> для этого? Я хотел бы использовать подход с лучшей практикой здесь, а не вмешиваться, создавая отдельные экземпляры самостоятельно, что, кажется, вызывает много работы, поскольку оно не хорошо документировано и, несомненно, не будет следовать лучшим практикам, поскольку ASP.NET Core использует инъекции зависимостей для таких вещей (что также разумно в моем оппионе).

Другими словами: Мне нужно использовать зависимую инъекцию снаружи контроллера.

+0

вы можете быть заинтересованы в моем проекте, который обеспечивает управление для пользователей удостоверений, ролями и утверждениями https://github.com/joeaudette/cloudscribe –

ответ

24

Вот пример для ваших потребностей, мигрирует и семена базы данных при запуске:

Создать статический класс:

public static class RolesData 
{ 
    private static readonly string[] Roles = new string[] {"Administrator", "Editor", "Subscriber"}; 

    public static async Task SeedRoles(IServiceProvider serviceProvider) 
    { 
     using (var serviceScope = serviceProvider.GetRequiredService<IServiceScopeFactory>().CreateScope()) 
     { 
      var dbContext = serviceScope.ServiceProvider.GetService<ApplicationDbContext>(); 

      if (dbContext.Database.GetPendingMigrations().Any()) 
      { 
       await dbContext.Database.MigrateAsync(); 

       var roleManager = serviceScope.ServiceProvider.GetRequiredService<RoleManager<IdentityRole>>(); 

       foreach (var role in Roles) 
       { 
        if (!await roleManager.RoleExistsAsync(role)) 
        { 
         await roleManager.CreateAsync(new IdentityRole(role)); 
        } 
       } 
      } 
     } 
    } 
} 

И в Startup.cs:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) 
{ 
    ... 

    RolesData.SeedRoles(app.ApplicationServices).Wait(); 
} 
+1

Если вы используете миграции, условие 'if (await db.Database.EnsureCreatedAsync())' false ', поэтому роли не создаются. – Artholl

+0

@Artholl Хороший улов. Я заменяю 'if (dbContext.Database.GetPendingMigrations(). Any())' и 'await dbContext.Database.MigrateAsync();' – tmg

+0

Попробуйте использовать IF только в том случае, если выполняются миграции ... Что-то вроде 'if (dbContext .Database.GetPendingMigrations(). Any()) await dbContext.Database.MigrateAsync(); ' – Yuki

5

Я бы предпочел чтобы засеять данные только в том случае, если в базе данных уже нет ролей. Других слов сохранить роль только тогда, когда приложение работает в первый раз:

public static class RolesData 
{ 
    private static readonly string[] Roles = new string[] { "Administrator", "Editor", "Subscriber" }; 

    public static async Task SeedRoles(IServiceProvider serviceProvider) 
    { 
     using (var serviceScope = serviceProvider.GetRequiredService<IServiceScopeFactory>().CreateScope()) 
     { 
      var dbContext = serviceScope.ServiceProvider.GetService<AppDbContext>(); 

      if (!dbContext.UserRoles.Any()) 
      { 
       var roleManager = serviceProvider.GetRequiredService<RoleManager<IdentityRole>>(); 

       foreach (var role in Roles) 
       { 
        if (!await roleManager.RoleExistsAsync(role)) 
        { 
         await roleManager.CreateAsync(new IdentityRole(role)); 
        } 
       } 
      } 

     } 
    } 
} 

И на Startup.cs:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) 
{ 
    ... 

    RolesData.SeedRoles(app.ApplicationServices).Wait(); 
}