locked
DatabaseInitializer is in different project RRS feed

  • Question

  • User-234441352 posted

    Hi,

    I am developing an application in asp.net mvc core 2.1 with core ef 2.1. 

    This is the following hierarchy of my application:

     Web.UI  Project    -> (Call)  -> DAL (DBContext + Repository) Project  -> (Call) ->  Manager ( DatabaseInitializer ) Project

    Web UI Project ( Migrations - files )

      I need to execute the Add-Migration   commands.

    I 'll run the Add-Migrations on which projects : 

    1). Web.UI Project

    2). DAL Project

    3). Manager Project

    Tuesday, October 2, 2018 7:24 PM

Answers

  • User475983607 posted

    I assume you want the DbContext and migrations files in the DAL Project where the startup project is the Web App or Web API.  I don't understand the purpose of the Manager Project.   I also assume you'll be using DI to inject the context into you service APIs and/or repository.  The later can be separate projects or part of the DAL Project.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, October 2, 2018 7:54 PM
  • User1520731567 posted

    Hi mehmoodahmed,

    I 'll run the Add-Migrations on which projects : 

    I think run the Add-Migrations on DAL (DBContext + Repository) Project better.(the place where the model,dbcontext in )

    When you develop a new application, your data model changes frequently, and each time the model changes, it gets out of sync with the database. You have configured the Entity Framework to automatically drop and re-create the database each time you change the data model.

    When you add, remove, or change entity classes or change your DbContext class, the next time you run the application it automatically deletes your existing database, creates a new one that matches the model, and seeds it with test data.

    This method of keeping the database in sync with the data model works well until you deploy the application to production. 

    Repository Pattern With ASP.NET MVC And Entity Framework. Repository Pattern is used to create an abstraction layer between data access layer and business logic layer of an application. Repositorydirectly communicates with data access layer [DAL] and gets the data and provides it to business logic layer [BAL].

    Best Regards.

    Yuki Tao

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Wednesday, October 3, 2018 6:48 AM
  • User1520731567 posted

    Hi mehmoodahmed,

    It seems that you are using 3-tier architecture.

    1.UI(User Interface layer):This is the topmost level of the application. The presentation tier displays information related to such services as browsing merchandise, purchasing and shopping cart contents. It communicates with other tiers by which it puts out the results to the browser/client tier and all other tiers in the network. In simple terms, it is a layer which users can access directly (such as a web page, or an operating system's GUI).

    2.BLL(Business Logic Layer):The logical tier is pulled out from the presentation tier and, as its own layer, it controls an application’s functionality by performing detailed processing.

    3.DAL(Data access layer):The data tier includes the data persistence mechanisms (database servers, file shares, etc.) and the data access layer that encapsulates the persistence mechanisms and exposes the data. The data access layer should provide an API to the application tier that exposes methods of managing the stored data without exposing or creating dependencies on the data storage mechanisms. Avoiding dependencies on the storage mechanisms allows for updates or changes without the application tier clients being affected by or even aware of the change.

    DAL is the bottom layer of this architecture.

    So,I still recommend you could run the Add-Migrations on DAL,it is related to data.

    In addition,it should be:

    Web.UI  Project    -> (Call)  -> Manager (Business Logic) Project -> (Call)  -> DAL (DatabaseInitializer+DBContext + Repository) Project 

    Best Regards.

    Yuki Tao

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Thursday, October 4, 2018 2:41 AM

All replies

  • User475983607 posted

    I assume you want the DbContext and migrations files in the DAL Project where the startup project is the Web App or Web API.  I don't understand the purpose of the Manager Project.   I also assume you'll be using DI to inject the context into you service APIs and/or repository.  The later can be separate projects or part of the DAL Project.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, October 2, 2018 7:54 PM
  • User1520731567 posted

    Hi mehmoodahmed,

    I 'll run the Add-Migrations on which projects : 

    I think run the Add-Migrations on DAL (DBContext + Repository) Project better.(the place where the model,dbcontext in )

    When you develop a new application, your data model changes frequently, and each time the model changes, it gets out of sync with the database. You have configured the Entity Framework to automatically drop and re-create the database each time you change the data model.

    When you add, remove, or change entity classes or change your DbContext class, the next time you run the application it automatically deletes your existing database, creates a new one that matches the model, and seeds it with test data.

    This method of keeping the database in sync with the data model works well until you deploy the application to production. 

    Repository Pattern With ASP.NET MVC And Entity Framework. Repository Pattern is used to create an abstraction layer between data access layer and business logic layer of an application. Repositorydirectly communicates with data access layer [DAL] and gets the data and provides it to business logic layer [BAL].

    Best Regards.

    Yuki Tao

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Wednesday, October 3, 2018 6:48 AM
  • User-234441352 posted

    thank you mgebhard and Yooki.

    Actually I wanted to implement a good solution. 

    DAL project contain DbContext and Repositories.

    Manager project call repositories.

    I separated one project to two projects.

    Initially DbContext (models), repositories and all manager were in DAL project then I separated the managers.

    Now what is my issue ?

    My DatabaseInitializer is using AccountManager manager class.

    Now please suggest what is better for me ?

    using DAL.Models;
    using Microsoft.AspNetCore.Identity;
    using Microsoft.EntityFrameworkCore;
    using Microsoft.Extensions.Logging;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using DAL.Core;
    using Manager.Interfaces;
    
    namespace DAL
    {
        public interface IDatabaseInitializer
        {
            Task SeedAsync();
        }
        public class DatabaseInitializer : IDatabaseInitializer
        {
            private readonly ApplicationDbContext _context;
            private readonly IAccountManager _accountManager;
            private readonly ILogger _logger;
    
            public DatabaseInitializer(ApplicationDbContext context, IAccountManager accountManager, ILogger<DatabaseInitializer> logger)
            {
                _accountManager = accountManager;
                _context = context;
                _logger = logger;
            }
    
            public async Task SeedAsync()
            {
                await _context.Database.MigrateAsync().ConfigureAwait(false);
    
                if (!await _context.Users.AnyAsync())
                {
                    _logger.LogInformation("Generating inbuilt accounts");
    
                    const string adminRoleName = "power";
                    const string userRoleName = "ushr";
    
                    await EnsureRoleAsync(adminRoleName, "Default administrator", ApplicationPermissions.GetAllPermissionValues());
                    await EnsureRoleAsync(userRoleName, "Default user", new string[] { });                
    
                    await CreateUserAsync("adm", "pa", "rator", "ad@y.com", "+1 (123) 1212000", new string[] { adminRoleName });
                    await CreateUserAsync("usr", "pa", "Standard", "us@g.com", "+1 (123) 454-78787", new string[] { userRoleName });
    
                    _logger.LogInformation("Inbuilt account generation completed");
                }
    
              
                {
                    _logger.LogInformation("Seeding initial data");
    
                   await _context.SaveChangesAsync();
    
                    _logger.LogInformation("Seeding initial data completed");
                }
            }
    
            private async Task EnsureRoleAsync(string roleName, string description, string[] claims)
            {
                if ((await _accountManager.GetRoleByNameAsync(roleName)) == null)
                {
                    ApplicationRole applicationRole = new ApplicationRole(roleName, description);
    
                    var result = await this._accountManager.CreateRoleAsync(applicationRole, claims);
    
                    if (!result.Item1)
                        throw new Exception($"Seeding \"{description}\" role failed. Errors: {string.Join(Environment.NewLine, result.Item2)}");
                }
            }
    
            private async Task<ApplicationUser> CreateUserAsync(string userName, string password, string fullName, string email, string phoneNumber, string[] roles)
            {
                ApplicationUser applicationUser = new ApplicationUser
                {
                    UserName = userName,
                    FullName = fullName,
                    Email = email,
                    PhoneNumber = phoneNumber,
                    EmailConfirmed = true,
                    IsEnabled = true
                };
    
                var result = await _accountManager.CreateUserAsync(applicationUser, roles, password);
    
                if (!result.Item1)
                    throw new Exception($"Seeding \"{userName}\" user failed. Errors: {string.Join(Environment.NewLine, result.Item2)}");
    
    
                return applicationUser;
            }
        }
    }
    


     

     

    Wednesday, October 3, 2018 6:08 PM
  • User1520731567 posted

    Hi mehmoodahmed,

    It seems that you are using 3-tier architecture.

    1.UI(User Interface layer):This is the topmost level of the application. The presentation tier displays information related to such services as browsing merchandise, purchasing and shopping cart contents. It communicates with other tiers by which it puts out the results to the browser/client tier and all other tiers in the network. In simple terms, it is a layer which users can access directly (such as a web page, or an operating system's GUI).

    2.BLL(Business Logic Layer):The logical tier is pulled out from the presentation tier and, as its own layer, it controls an application’s functionality by performing detailed processing.

    3.DAL(Data access layer):The data tier includes the data persistence mechanisms (database servers, file shares, etc.) and the data access layer that encapsulates the persistence mechanisms and exposes the data. The data access layer should provide an API to the application tier that exposes methods of managing the stored data without exposing or creating dependencies on the data storage mechanisms. Avoiding dependencies on the storage mechanisms allows for updates or changes without the application tier clients being affected by or even aware of the change.

    DAL is the bottom layer of this architecture.

    So,I still recommend you could run the Add-Migrations on DAL,it is related to data.

    In addition,it should be:

    Web.UI  Project    -> (Call)  -> Manager (Business Logic) Project -> (Call)  -> DAL (DatabaseInitializer+DBContext + Repository) Project 

    Best Regards.

    Yuki Tao

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Thursday, October 4, 2018 2:41 AM
  • User-234441352 posted
    Thank you Yuri. Yes I am familiar with 3-tier or n-tier and the purpose of n-tier. The problem was in my databaseinitializer and seed.
    And seed was using a manager. If I have to change the logic and place it in DAL then I ll have to change the logic. Can't I place in web project where DAL and manager can be accessed together. OK. If not any suitable solution then it's better to change and place in DAL
    Thursday, October 4, 2018 4:22 AM