DataInitializer.cs

240 lines | 6.887 kB Blame History Raw Download
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

using Microsoft.EntityFrameworkCore;
using Microsoft.AspNetCore.Identity;

using WebFileServ.Entitites.Identity;

using WebFileServ.DAL.DataBase.EF;

namespace WebFileServ.DAL
{

    /// <summary>
    /// Класс для управления состоянием БД
    /// </summary>
    public class DataInitializer
    {
        private readonly ApplicationDbContext Context;
        private readonly ApplicationDbContextW ContextW;

        private readonly UserManager<ApplicationUser> UserManager;
        private readonly RoleManager<ApplicationRole> RoleManager;



        // TODO: Вынести данные параметры в конфиги приложения, зависящие от окружения

        /// <summary>
        /// Удалять базу при каждом запуске приложения.
        /// !!Внимание использовать только для тестовой среды.
        /// </summary>
        public bool ReCreateDataBase { set; get; }

        /// <summary>
        /// Автоматически применять миграцию при запуске приложения
        /// </summary>
        public bool AutoApplyMigration { set; get; }



        public DataInitializer
            (
            ApplicationDbContext context,
            ApplicationDbContextW contextW,
            UserManager<ApplicationUser> userManager,
            RoleManager<ApplicationRole> roleManager
            )
        {
            Context = context;
            ContextW = contextW;
            UserManager = userManager;
            RoleManager = roleManager;
        }



        public async Task Init()
        {
            await RemoveDbIfExsist();
            await ApplyMigrations();

            await CreateAdminUserIfNotExsist();
        }



        private async Task RemoveDbIfExsist()
        {
            if (!ReCreateDataBase)
            {
                return;
            }

            await Context.Database.EnsureDeletedAsync();
        }

#pragma warning disable CS1998 // В асинхронном методе отсутствуют операторы await, будет выполнен синхронный метод
        private async Task ApplyMigrations()
#pragma warning restore CS1998 // В асинхронном методе отсутствуют операторы await, будет выполнен синхронный метод
        {
            if (!AutoApplyMigration)
            {
                return;
            }

            Context.Database.Migrate();
        }


        /// <summary>
        /// Иницилизация пользователя администратора по-умолчанию.
        /// Иницилизация роли администраторов
        /// </summary>
        /// <returns></returns>
        private async Task CreateAdminUserIfNotExsist()
        {
            try
            {

                var email = "admin@admin";
                var password = "demo";

                var roleName = "AdminRole";


                var adminRole = await RoleManager
                    .FindByNameAsync(roleName);

                if (adminRole == null)
                {
                    var createRoleResult = await RoleManager.CreateAsync(
                        new ApplicationRole(roleName)
                        );

                    if (!createRoleResult.Succeeded)
                    {
                        throw new Exception(
                            createRoleResult.Errors.FirstOrDefault()?.Description
                            );
                    }
                }


                var adminUser = await UserManager
                    .FindByNameAsync(email);

                if (adminUser == null)
                {
                    var createUserResult = await UserManager
                        .CreateAsync(
                            new ApplicationUser()
                            {
                                Email = email,
                                UserName = email
                            },
                            password
                        );

                    if (!createUserResult.Succeeded)
                    {
                        throw new Exception(
                            createUserResult.Errors.FirstOrDefault()?.Description
                            );
                    }


                    //adminUser = await UserManager
                    //    .FindByNameAsync(email);

                    //var addToRoleResult = await UserManager
                    //    .AddToRoleAsync(adminUser, roleName);

                    //if (!addToRoleResult.Succeeded)
                    //{
                    //    throw new Exception(
                    //        addToRoleResult.Errors.FirstOrDefault()?.Description
                    //        );
                    //}


                    var aUser = ContextW.Users.FirstOrDefault();
                    var aRole = ContextW.Roles.FirstOrDefault();


                    aUser.RolesDict = new Dictionary<long, ApplicationRole>()
                    {
                        [aRole.Id] = aRole
                    };

                    ContextW.SaveChanges();


                    //var user = context
                    //     .Users
                    //     .Include(e => e.Roles)
                    //     .ThenInclude(e => e.Role)
                    //     .FirstOrDefault(e => e.Email == email);

                    //var a = context.UserRole.FirstOrDefault();

                    aUser = ContextW
                        .Users
                        .Include(e => e.Roles)
                        .ThenInclude(e => e.Role)
                        .FirstOrDefault();
                }
            }
            catch (Exception ex)
            {

            }
        }




        #region Dispose

        private bool disposed = false;

        // реализация интерфейса IDisposable.
        public void Dispose()
        {
            Dispose(true);
            // подавляем финализацию
            GC.SuppressFinalize(this);
        }

        protected virtual void Dispose(bool disposing)
        {
            if (!disposed)
            {
                if (disposing)
                {
                    // Освобождаем управляемые ресурсы
                    Context.Dispose();
                    ContextW.Dispose();

                    UserManager.Dispose();
                    RoleManager.Dispose();
                }
                // освобождаем неуправляемые объекты
                disposed = true;
            }
        }

        // Деструктор
        ~DataInitializer()
        {
            Dispose(false);
        }

        #endregion

    }
}