Open Closed

How to generate Domain Layer from Database? #18


0
trisledinh created

Firstly, I really like your idea and workload to make asp.net Boilerplate community. I like boilerplate. I am starting use Boilerplate to make our stable framework for building enterprise application. At the moment, I have some question:

How to generate Domain Layer (Entities, Respository, DbContext, DTO)? Using ADO.NET Entity Data Model or write your self? How to generate Application Services Layer?

With project which has many table, we would like to generate Domain Layer and Application Services Layer automatically to save resources.

Can you help me?

Thank you very much.


9 Answer(s)
  • 0
    hikalkan created

    Hi,

    Thanks a lot.

    Entities and DbContext: You can generate code-first entities using Visual Studio from an existing database (search web for it). Then you can modify them to derive from Entity class. Repositories: No need to create repositories since you can inject and use IRepository

    ASP.NET Boilerplate is first designed for new application with empty databases rather than migrating existing databases or applications. ASP.NET Boilerplate is not a code generation tool. Also, in DDD, you should think carefully on Entities, DTOs and application layer. They are not things can be automatically generated (At least I think like that). Creating a repository, a DTO, CRUD application service and an entity for a database table is not DDD. Even it's possible, you will change a lot after creating. Yes, maybe we can create a tool to firstly creating these classes to help us. It may be a starting point. But there is no such a tool in this moment If you build such a tool, please share with us since a few people also asked this question before :).

    Have a nice day.

  • 0
    trisledinh created

    Hi,

    Thank you very much.

    I will try to using T4 Template for generation. Today, I try to implement Domain, Application Service but there is one error showing as:

    Can't create component 'ModuleZeroSampleProject.Uploading.UpAttachAppService' as it has dependencies to be satisfied. 'ModuleZeroSampleProject.Uploading.UpAttachAppService' is waiting for the following dependencies:\r\n- Service 'Abp.Domain.Repositories.IRepository`1[[ModuleZeroSampleProject.Uploading.UpAttach, ModuleZeroSampleProject.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]' which was not registered.

    Steps which I did:

    • Add UpAttach.cs in Core Project (ex: public class UpAttach : CreationAuditedEntity<int, User>)

    • Add interface IUpAttachServices.cs in Application Project (ex: public interface IUpAttachAppService : IApplicationService);

    • Add implement class UpAttachServices.cs in ApplicationServices (ex:

    [AbpAuthorize]
        public class UpAttachAppService : ApplicationService, IUpAttachAppService
        {
            private readonly IRepository<UpAttach> _attachRepository;
            private readonly IRepository<User, long> _userRepository;
            private readonly IUnitOfWorkManager _unitOfWorkManager;
    
            public UpAttachAppService(IRepository<UpAttach> attachRepository, IRepository<User, long> userRepository, IUnitOfWorkManager unitOfWorkManager)
            {
                _attachRepository = attachRepository;
                _userRepository = userRepository;
                _unitOfWorkManager = unitOfWorkManager;
            }
    
            public PagedResultOutput<AttachDto> GetAttachs(GetQuestionsInput input)
            {
                if (input.MaxResultCount <= 0)
                {
                    input.MaxResultCount = SettingManager.GetSettingValue<int>(MySettingProvider.QuestionsDefaultPageSize);
                }
    
                var questionCount = _attachRepository.Count();
                var questions =
                    _attachRepository
                        .GetAll()
                        .Include(q => q.CreatorUser)
                        .OrderBy(input.Sorting)
                        .PageBy(input)
                        .ToList();
    
                return new PagedResultOutput<AttachDto>
                       {
                           TotalCount = questionCount,
                           Items = questions.MapTo<List<AttachDto>>()
                       };
            }
    
        }
    

    )

    But when I compose from Fiddle2 with URL "http://localhost:6242/api/services/app/upAttach/GetAttachs", the error was shown. I try to clarify it but not successful.

    Can you help me?

    Thank a lot!

  • 0
    hikalkan created

    Hi,

    Some questions:

    • Did you started from template generated by aspnetboilerplate.com?
    • Did you add your entity to your DbContext?
    • Did you derive UpAttach from Entity?
  • 0
    trisledinh created

    Yes,

    I developed from ModuleZeroTemplate. I have fixed it by run updating database in Package Console Manager to synchonize entity object with table in database. Now, I can define step to step:

    Step 1: Create new entity class in Project Core Step 2: Add Entity to DbContext Step 3: Run command in Package Console Manager as the following: Add-Migration entity_name --> to add new migration file Update-Database -Verbose --> to add table in database Step 4: Add interface and class in Application Services Layer Step 5: Add new menu in NavigationProvider Step 6: Add html and js file in Presentation Layer Step 7: Start customization

    Thank a lot. I am implementing registration account feature and sending email. Dear Hikalkan, have you recommendation about this feature?

    Thank your very much.

  • 0
    hikalkan created

    Yeah, you found it :) Creating a well structured, domain-driven and layered application is not easy. ABP tries to make it easier and straightforward. You can have different models for registration. Simple one is to create users by an admin. Other one is to allow users register themselves using email activation. This is completely upon your needs.

  • 0
    trisledinh created

    Thank you!

    I tried a multi-level menu navigation which has child menus but it seems child menu is not working. I implemented it with single page and multi page template, but it is not successful. How to fix it?

    And also I have some other questions:

    • How to integrate with Oracle Database?
    • How to call Stored Procedure from Repository?

    I hope you have free time to help me. Thank you very much.

  • 0
    hikalkan created

    Hi,

    Startup template is just a minimal template, you should change it upon yor needs. See header.js and header.cshtml in App\Main\views\layout folder of SPA (or Views\Layout_TopMenu.cshtml in MPA). You can change it freely.

    For your other questions:

    • ABP uses EntityFramework or NHibernate. You can search web to find articles on working oracle with EF 6. This is not directly related to ABP. Probably you will change connection string and add come dlls to your project.
    • Create a custom repository method (http://www.aspnetboilerplate.com/Pages/ ... oryMethods) and call your stored procedure using Context.Database. You can find many documents on web about that.

    Have a nice day.

  • 0
    trisledinh created

    Hi,

    I have added new custom repository to implement EF6 of Oracle Database. But when call application services from client, throwing server error

    "An exception of type 'Castle.MicroKernel.ComponentNotFoundException' occurred in Castle.Windsor.dll but was not handled in user code. Additional information: No component for supporting the service ModuleZeroSampleProject.Enterprises.UploadingEntities was found"
    

    It mean that ModuleZeroSampleProject.Enterprises.UploadingEntities was not registered assembly when implement Dependency Injection Pattern. But I don't know when registered this dbcontext class. I did as the following:

    Step 1: Install ODTwithODAC from oracle Step 2: Install Oracle EF6 from Nuget Package Console Step 3: Add EntityDataModel to Core project (generate code from database) Step 4: Add RepositoryBase Class into Entity Framework Project such as

    namespace ModuleZeroSampleProject.EntityFramework.Repositories
    {
        public class UploadingRepositoryBase<TEntity, TPrimaryKey> : EfRepositoryBase<UploadingEntities, TEntity, TPrimaryKey>
        where TEntity : class, IEntity<TPrimaryKey>
        {
            public UploadingRepositoryBase(IDbContextProvider<UploadingEntities> dbContextProvider)
                : base(dbContextProvider)
            {
            }
    
            //add common methods for all repositories
        }
    
        //A shortcut for entities those have integer Id
        public class UploadingRepositoryBase<TEntity> : UploadingRepositoryBase<TEntity, int>
            where TEntity : class, IEntity<int>
        {
            public UploadingRepositoryBase(IDbContextProvider<UploadingEntities> dbContextProvider)
                : base(dbContextProvider)
            {
            }
    
            //do not add any method here, add to the class above (because this class inherits it)
        }
    }
    

    Step 5: Add IUploadingRepository to Core Project

    namespace ModuleZeroSampleProject.Enterprises
    {
        public interface IUploadingRepository : IRepository<CV_ENTERPRISE, int>
        {
            List<CV_ENTERPRISE> GetEnterprise(int? enterpriseId);
        }
    }
    

    Step 6: Add UploadingRepository to EntityFramework Project Step 7: Add IUploadingService and UploadingServices to ApplicationModule Project Step 8: Modify client to get method from Uploading Services.

    All thing was built successfully, run OK. But when call get method from Uploading Services, throwing error not registered assembly.

    Can you help me?

    Thank you very much.

  • 0
    trisledinh created

    Can you help me?