Skip to content

Instantly share code, notes, and snippets.

@princeppy
Created February 26, 2018 05:03
Show Gist options
  • Save princeppy/b8de67ef22254abdb51797ed46a00d90 to your computer and use it in GitHub Desktop.
Save princeppy/b8de67ef22254abdb51797ed46a00d90 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(AbpZeroOwinModule),
            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% GTR 3 exit 1
    (robocopy "$(TargetDir)App\MIT" "$(SolutionDir)JPY.Zero.Web\App\MIT" /MIR /XF *.pdb *.xml *.dll /NP /NJH /IS ) ^& IF %ERRORLEVEL% GTR 3 exit 1
    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

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