Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save princeppy/ae0f24417f6ccdc7ccc73587ed9f1769 to your computer and use it in GitHub Desktop.
Save princeppy/ae0f24417f6ccdc7ccc73587ed9f1769 to your computer and use it in GitHub Desktop.

How To: Setting up ASPNetZero With Modular Application

Preparing AspNetZero Project

  1. Create a github repo "jpy-d360"

    clone the above create repo to working directory

  2. Get the latest version of AspNetZero Binary

    Company name : "JPY" Project name : "Zero" which will read as "JPY.Zero", make sure this is same always

  3. Open the Project

    1. Unblock the downloaded project

    2. unzip to the into the above working github repo 'jpy-360'

    3. open the project in visual studio

    4. Restore nuget packages

    5. Set JPY.Zero.Web as startup Project

    6. Update the web.config for database connection string

      Source: Web.config

      <add name="Default" connectionString="Data Source=(local); Initial Catalog=JPYD360; Integrated Security=True; MultipleActiveResultSets=True;" providerName="System.Data.SqlClient" />
      <add name="Default_Debug" connectionString="Server=XXXXX; Database=JPYD360_Debug; Integrated Security=false; MultipleActiveResultSets=True; user=jpyd360;pwd=*******" providerName="System.Data.SqlClient" />
      

      Source: Web.Release.config

      <add name="Default" connectionString="Server=XXXXX; Database=JPYD360_Debug; Integrated Security=false; MultipleActiveResultSets=True; user=jpyd360;pwd=*******" providerName="System.Data.SqlClient" xdt:Transform="SetAttributes" xdt:Locator="Match(name)" />
      
    7. Updating Database (Initial)

      Update-Database -Verbose -ProjectName JPY.Zero.EntityFramework
      
    8. Run and execute the project to see its working fine.

  4. Updating the AspNetZero to the latest abp

    1. Update Abp Packages

      Get-Project -All | Get-Package | ?{ $_.Id -like 'Abp*' } | Update-Package
      
    2. Clean solution and unload all projects and build project one by one a. JPY.Zero.Core a. JPY.Zero.EntityFramework a. JPY.Zero.Application a. JPY.Zero.WebApi a. JPY.Zero.Web a. ...... then rest of projects

    3. At every project clean build and rectify error and possible warning and go to next project

    4. Once Build Successfull

    5. Set JPY.Zero.Web as startup Project

    6. Update-Database -Verbose -ProjectName JPY.Zero.EntityFramework

    7. Run the solution

Adding Modules

  1. Create 'D360' Module Project structure

    1. Create a solution folder 'D360'

    2. Create 4 'c#' Library '.net4.6.1' Project with names below with in 'D360'

      1. JPY.D360.Core
      2. JPY.D360.EntityFramework
      3. JPY.D360.Application
      4. JPY.D360.Web
    3. Change the new project Default Namespace except JPY.D360.Web as JPY.Zero

    4. Run the package manager for each project as below

      1. In JPY.D360.Core, Install below packages and get a reference from JPY.Zero.Core

        Install-Package Abp.Zero.Ldap -Verbose -ProjectName JPY.D360.Core
        Install-Package Abp.AutoMapper -Verbose -ProjectName JPY.D360.Core
        
      2. In JPY.D360.EntityFramework, Install below packages and get a reference from JPY.D360.Core and JPY.Zero.EntityFramework

        Install-Package Abp.Zero.EntityFramework -Verbose -ProjectName JPY.D360.EntityFramework
        Install-Package Abp.AutoMapper -Verbose -ProjectName JPY.D360.EntityFramework
        
      3. In JPY.D360.Application, Install below packages and get a reference from JPY.D360.Core and JPY.Zero.Application

        Install-Package Abp.Zero.Ldap -Verbose -ProjectName JPY.D360.Application
        Install-Package Abp.AutoMapper -Verbose -ProjectName JPY.D360.Application
        Install-Package Microsoft.AspNet.Identity.Core -Verbose -ProjectName JPY.D360.Application
        Install-Package EPPlus -Verbose -ProjectName JPY.D360.Application
        Install-Package EntityFramework -Verbose -ProjectName JPY.D360.Application
        Install-Package System.Linq.Dynamic -Verbose -ProjectName JPY.D360.Application
        
      4. In JPY.D360.Web, Install below packages and get a reference from JPY.Zero.Core, JPY.D360.Core, JPY.D360.EntityFramework and JPY.D360.Application

        Install-Package Abp.Web.Mvc -Verbose -ProjectName JPY.D360.Web
        Install-Package Abp.Web.Api -Verbose -ProjectName JPY.D360.Web
        Install-Package Abp.Zero.EntityFramework -ProjectName JPY.D360.Web
        
      5. In JPY.Zero.Web, additionally to the default references get a reference from JPY.D360.Web

    5. Change the Dependency

      1. In JPY.Zero.Web

        /*
        [DependsOn(
            typeof(AbpWebMvcModule),
            typeof(ZeroDataModule),
            typeof(ZeroApplicationModule),
            typeof(ZeroWebApiModule),
            typeof(AbpWebSignalRModule),
            typeof(AbpRedisCacheModule), //AbpRedisCacheModule dependency can be removed if not using Redis cache
            typeof(AbpHangfireModule))] //AbpHangfireModule dependency can be removed if not using Hangfire
        */
        [DependsOn(typeof(D360.Web.D360WebModule),
            typeof(ZeroWebApiModule),
            typeof(AbpWebSignalRModule),
            typeof(AbpRedisCacheModule), //AbpRedisCacheModule dependency can be removed if not using Redis cache
            typeof(AbpHangfireModule), //AbpHangfireModule dependency can be removed if not using Hangfire
            typeof(AbpWebMvcModule))]
        public class ZeroWebModule : AbpModule
        {
        }
      2. In JPY.D360.XXXX projects make required changes and run the project

        namespace JPY.Zero
        {
            // Core (domain) module of the application.
            [DependsOn(typeof(ZeroCoreModule))]
            public class D360CoreModule : AbpModule
            {
            }
        }
        namespace JPY.Zero
        {
            // Entity framework module of the application.
            [DependsOn(typeof(AbpZeroEntityFrameworkModule), typeof(D360CoreModule), typeof(ZeroDataModule))]
            public class D360DataModule : AbpModule
            {
            }
        }
        namespace JPY.Zero
        {
            // Application layer module of the application.
            [DependsOn(typeof(D360CoreModule), typeof(ZeroApplicationModule))]
            public class D360ApplicationModule : AbpModule
            {
            }
        }
        namespace JPY.D360.Web
        {
            [DependsOn(typeof(D360DataModule), typeof(D360ApplicationModule))]
            public class D360WebModule : AbpModule
            {
            }
        }
      3. Run the Project and make sure everything till now is working fine... :sm

  2. Trick/Important Configuring Web project

    In JPY.D360.Web post build, set rule to robocopy

    (robocopy "$(TargetDir)App\D360" "$(SolutionDir)JPY.Zero.Web\App\D360" /MIR /XF *.pdb *.xml *.dll /NP /NJH /IS ) ^& IF %ERRORLEVEL% LEQ 3 exit 0
    (robocopy "$(TargetDir)App\MIT" "$(SolutionDir)JPY.Zero.Web\App\MIT" /MIR /XF *.pdb *.xml *.dll /NP /NJH /IS ) ^& IF %ERRORLEVEL% LEQ 3 exit 0
    
  3. Inherited DbContext

    1. In project JPY.Zero.Core,

      1. create an IRepository Interface for the DbContextBaseRepo

        Source \JPY.Zero.Core\Domain\Repositories\IZeroRepositoryBase.cs

        namespace JPY.Zero.Domain.Repositories
        {
            using Abp.Domain.Repositories;
            public interface IZeroRepositoryBase<T, TPrimaryKey> : IRepository<T, TPrimaryKey>
                where T : class, Abp.Domain.Entities.IEntity<TPrimaryKey>
            { }
        
            public interface IZeroRepositoryBase<T> : IRepository<T>
                where T : class, Abp.Domain.Entities.IEntity<int>
            { }
        }
      2. create an IRepository Interface for the derived IZeroRepositoryBase

        Source \JPY.Zero.Core\Domain\Repositories\ID360RepositoryBse.cs

        namespace JPY.Zero.Domain.Repositories
        {
            public interface ID360RepositoryBase<T, TPrimaryKey> : IZeroRepositoryBase<T, TPrimaryKey>
                where T : class, Abp.Domain.Entities.IEntity<TPrimaryKey>
            { }
        
            public interface ID360RepositoryBase<T> : ID360RepositoryBase<T, int>
                where T : class, Abp.Domain.Entities.IEntity<int>
            { }
        }
    2. In Project JPY.Zero.EntityFramework,

      1. create an implementation of the above IZeroRepositoryBase Interface.

        Source \JPY.Zero.EntityFramework\EntityFramework\Repositories\ZeroRepositoryBase.cs

        namespace JPY.Zero.EntityFramework.Repositories
        {
            public class ZeroRepositoryBase<TEntity, TPrimaryKey> : EfRepositoryBase<ZeroDbContext, TEntity, TPrimaryKey> , IZeroRepositoryBase<TEntity, TPrimaryKey>
                where TEntity : class, IEntity<TPrimaryKey>
            {
                public ZeroRepositoryBase(IDbContextProvider<ZeroDbContext> dbContextProvider) : base(dbContextProvider) { }
                //add your common methods for all repositories
            }
        
            public class ZeroRepositoryBase<TEntity> : ZeroRepositoryBase<TEntity, int> , IZeroRepositoryBase<TEntity>
                where TEntity : class, IEntity<int>
            {
                public ZeroRepositoryBase(IDbContextProvider<ZeroDbContext> dbContextProvider) : base(dbContextProvider) { }
                //do not add any method here, add to the class above (since this inherits it)!!!
            }
        }
      2. Add an AutoRepositoryTypes to the Main DbContext

        [AutoRepositoryTypes(
            typeof(IZeroRepositoryBase<>),
            typeof(IZeroRepositoryBase<,>),
            typeof(ZeroRepositoryBase<>),
            typeof(ZeroRepositoryBase<,>)
        )]
        public class ZeroDbContext : AbpZeroDbContext<Tenant, Role, User> {
            // ......
        }
      3. In the ZeroDataModule under Initialize, Register the ZeroRepositoryBase

        IocManager.IocContainer.Register(Component.For(typeof(IRepository<>)).ImplementedBy(typeof(EntityFramework.Repositories.ZeroRepositoryBase<>)).LifestyleTransient().Named("IRepositoryImplementation"));
        IocManager.IocContainer.Register(Component.For(typeof(IRepository<,>)).ImplementedBy(typeof(EntityFramework.Repositories.ZeroRepositoryBase<,>)).LifestyleTransient().Named("IRepositoryOfPrimaryKeyImplementation"));
    3. In Project JPY.D360.EntityFramework,

      1. create an implementation of the above ID360RepositoryBase Interface.

        Source \JPY.D360.EntityFramework\EntityFramework\Repositories\D360RepositoryBase.cs

        namespace JPY.Zero.EntityFramework.Repositories
        {
            public class D360RepositoryBase<TEntity, TPrimaryKey> : ZeroRepositoryBase<TEntity,TPrimaryKey>
                where TEntity : class, IEntity<TPrimaryKey>
            {
                public D360RepositoryBase(IDbContextProvider<D360DbContext> dbContextProvider) : base(dbContextProvider) { }
                //do not add any method here, add to the class above (since this inherits it)
            }
            public abstract class D360RepositoryBase<TEntity> : D360RepositoryBase<TEntity,int>
                where TEntity : class, IEntity<int>
            {
                public D360RepositoryBase(IDbContextProvider<D360DbContext> dbContextProvider) : base(dbContextProvider) { }
                //do not add any method here, add to the class above (since this inherits it)
            }
        }
      2. create a derived D360DbContext as below

        namespace JPY.Zero.EntityFramework
        {
            [DefaultDbContext]
            [AutoRepositoryTypes(
                typeof(ID360RepositoryBase<>),
                typeof(ID360RepositoryBase<,> ),
                typeof(D360RepositoryBase<>),
                typeof(D360RepositoryBase<,>)
            )]
            public class D360DbContext : ZeroDbContext
            {
                //TODO: Define an IDbSet for your Entities...
                public D360DbContext() : base("Default") { }
                public D360DbContext(string nameOrConnectionString) : base(nameOrConnectionString) { }
                public D360DbContext(DbConnection connection) : base(connection) { }
            }
        }
      3. Inorder to avoid Found more than one concrete type for given DbContext Type error, lets create one DbContextTypeMatcher

        Source \JPY.D360.EntityFramework\EntityFramework\D360DbContextTypeMatcher.cs

        namespace JPY.Zero.EntityFramework
        {
            public class D360DbContextTypeMatcher : Abp.EntityFramework.DbContextTypeMatcher
            {
                public D360DbContextTypeMatcher(ICurrentUnitOfWorkProvider currentUnitOfWorkProvider) : base(currentUnitOfWorkProvider) { }
                public override Type GetConcreteType(Type sourceDbContextType)
                {
                    if (!sourceDbContextType.IsAbstract) return sourceDbContextType;
                    return base.GetConcreteType(sourceDbContextType);
                }
            }
        }
      4. In D360DataModule under PreInitialize, Initialize the D360DbContextTypeMatcher

        public override void PreInitialize()
        {
            // ....
            Configuration.ReplaceService(typeof(Abp.EntityFramework.IDbContextTypeMatcher), () =>
            {
                IocManager.Register<Abp.EntityFramework.IDbContextTypeMatcher, EntityFramework.D360DbContextTypeMatcher> (DependencyLifeStyle.Transient);
            });
            // ....
        }
    4. Run the project

  4. Enabling Migratation

    1. Enable migratation for JPY.D360.EntityFramework

      Enable-Migrations -Verbose -ProjectName JPY.D360.EntityFramework
      
    2. Add and enpty Migratation

      Add-Migration "Initial" -Verbose -ProjectName JPY.D360.EntityFramework -IgnoreChanges -Force
      
    3. Update Database

      Update-Database -Verbose -ProjectName JPY.D360.EntityFramework
      

###You are good to go

@buaziz
Copy link

buaziz commented Mar 14, 2017

any updates for the Core version ?

@lommez
Copy link

lommez commented Apr 9, 2017

When running my application i receive that exception message:

Could not find a concrete implementation of given DbContext type: Abp.Zero.EntityFramework.AbpZeroCommonDbContext2[[AspNetZero.Authorization.Roles.Role, AspNetZero.Core, Version=3.4.0.0, Culture=neutral, PublicKeyToken=null],[AspNetZero.Authorization.Users.User, AspNetZero.Core, Version=3.4.0.0, Culture=neutral, PublicKeyToken=null]], Abp.Zero.EntityFramework, Version=1.5.1.0, Culture=neutral, PublicKeyToken=null

Do you know what can be?

Thanks

@rvwoezik
Copy link

Please create a Core version, it will be appreciated

@hoangcurious
Copy link

hoangcurious commented Sep 19, 2017

Hi sir,
Thanks for your tut. Could you please to help me one thing:

  • After I changed D360DbContext conn string from "default" to "D360Conn", created new Entity named "D360Model" and run migration. --> Everything ok.
    After that, I created a new D360AppService used IRepository<D360Model> I faced an issue "The entity type D360Model is not part of the model for the current context."

Could you help me on this issue? I have tried some solutions but they didn't work

@acjh
Copy link

acjh commented Sep 19, 2017

@ASCSolution Use ID360RepositoryBase<D360Model>.

@hoangcurious
Copy link

hoangcurious commented Sep 20, 2017

Thank Aaron.
I could not find these folders (folder App) in my project, anyone can help?

(robocopy "$(TargetDir)App\D360" "$(SolutionDir)JPY.Zero.Web\App\D360" /MIR /XF *.pdb *.xml *.dll /NP /NJH /IS ) ^& IF %ERRORLEVEL% LEQ 3 exit 0
(robocopy "$(TargetDir)App\MIT" "$(SolutionDir)JPY.Zero.Web\App\MIT" /MIR /XF *.pdb *.xml *.dll /NP /NJH /IS ) ^& IF %ERRORLEVEL% LEQ 3 exit 0

@hoangcurious
Copy link

hoangcurious commented Sep 20, 2017

Can you create a post to starting with JPY.D360.Web project?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment