ABP框架學習筆記


ABP是“ASP.NET Boilerplate Project (ASP.NET樣板項目)”的簡稱。

ASP.NET Boilerplate是一個用最佳實踐和流行技術開發現代WEB應用程序的新起點,它旨在成為一個通用的WEB應用程序框架和項目模板。

官網:http://www.aspnetboilerplate.com

 

1.代碼使用的是         2.生成的代碼結構是:

3.各層介紹:

SIMS.Core: 領域核心層,是應用程序的核心。該層寶包括業務邏輯和規則。在該層可以定義數據庫對象實體,倉儲接口等。
SIMS.EntityFramwork: 主要是對數據庫表的操作。該層實現Core定義的倉儲接口。
SIMS.Applocation: 應用程序層,該層介於Core和展現層(SIMS.Web,SIMS.WebApi)之間。展現層通過它來和服務器交互。該層可以定義DTOS,AutoMapper(倉儲實體和數據庫實體的轉換。),定義IApplocationService接口。(在該層實現IApplicationService的都可以自動生成APIController,供展現層調用。注意,前端調用時候是名字操作的,默認的情況下在該層定義的接口名稱要以AppService結尾)
SIMS.Web和SIMS.WebApI組成前端展現層。實現用戶交互。

 

4.例子

做一個學歷表。表中只有主鍵和學歷名稱。

  1.在Core層建一個Entity的文件夾,用來存放數據庫實體,並且每個實體類都集成一個叫Entity<PK>的抽象類。該類已經定義了一個主鍵,主鍵類型可以是Entity<int>,Entity<long>

public class MajorType:Entity<int>
    {
        public string MajorName { get; set; }
    }

  2.在Core層建一個Repository文件夾,用來定義倉儲接口。這些接口都繼承現IRepository<T,int>T接口,T表示Entity里面的實體,int/long與實體的主鍵類型一致。(IRepository已經實現一些基本的方法)

//比如
public
interface IRepository<TEntity, TPrimaryKey> : IRepository, ITransientDependency where TEntity : class, IEntity<TPrimaryKey> { int Count(); int Count(Expression<Func<TEntity, bool>> predicate); Task<int> CountAsync(); Task<int> CountAsync(Expression<Func<TEntity, bool>> predicate); void Delete(TEntity entity); }

public interface IMajorRepository: IRepository<MajorType,int>
{

}

  3.在EntityFramework層下面的EntityFramework==>Repositories定義類實現Core層的倉儲接口。該文件下的類都會繼承SIMSRepositoryBase<T, int>類,實現Core層的倉庫接口。

public class MajorRepository : SIMSRepositoryBase<MajorType, int>, IMajorRepository
    {
        public MajorRepository(IDbContextProvider<SIMSDbContext> dbContextProvider) : base(dbContextProvider)
        {
        }
    }

  4.在Application層建立AppService,IAppService,DTOS,AutoMapper文件夾,用來實現特定的業務邏輯。 

    4.1首先在IAppService文件夾下定義用戶交互的接口。該文件夾下的接口都繼承IApplicationService接口。

public interface IMajorAppService:IApplicationService
    {
        List<MajorTypeInput> GetAll();

        void InsertorUpdate(MajorTypeInput input);
    }

    4.2在AppService文件夾下定義類來實現IAppService的接口。該文件夾下的類都實現IApplicationService和IAppService文件下的某個接口。注意,在Core層和EntityFrameWork都是但數據表操作,如果對多個表操作,實在該層進行的,通過構造函數注入來操作多表。

public class MajorAppService : IApplicationService, IMajorAppService
    {
        public readonly IMajorRepository _majorRepository;

        public MajorAppService(IMajorRepository majorRepository)
        {
            _majorRepository = majorRepository;
        }
        public List<MajorTypeInput> GetAll()
        {
            var list= _majorRepository.GetAllList();
           
            
            var l= Mapper.Map<List<MajorType>, List<MajorTypeInput>>(list);
            return l;
        }

        public void InsertorUpdate(MajorTypeInput input)
        {
            var l = Mapper.Map<MajorTypeInput, MajorType>(input);
            _majorRepository.InsertOrUpdate(l);
        }
    }

    4.3在DTO文件夾下面簡歷與展現層交互的input和output,該文件夾下的類實現IInputDto接口。用來進行數據驗證,如果想自定義數據驗證,還需要實現ICustomValidate接口,在AddValidationErrors(List<ValidationResult> results)方法里面寫。

public class MajorTypeInput:IInputDto,ICustomValidate
    {
        public int Id { get; set; }

        [Required]
        public string MajorName { get; set; }
public void AddValidationErrors(List<ValidationResult> results)
    {
        if (SendEmailToAssignedPerson && (!AssignedPersonId.HasValue || AssignedPersonId.Value <= 0))
        {
            results.Add(new ValidationResult("AssignedPersonId must be set if SendEmailToAssignedPerson is true!"));
        }
    }
}

    4.4在AutoMapper文件夾下面建幾個類來實現實體自動映射。要轉換的實體,將加好的實體類在AutoMapperWebConfig中初始化,然后再app_Start文件夾下的WebModule下的Initialize方法里面添加:AutoMapperWebConfig.Configure();

public class MajorProfile:Profile
    {
        protected override void Configure()
        {
            Mapper.Initialize(cfg => {
                cfg.CreateMap<MajorType, MajorTypeInput>();//type->input
                cfg.CreateMap<MajorTypeInput, MajorType>();//input->type
            });
        }
    }
public static class AutoMapperWebConfig
    {
        public static void Configure()
        {
            Mapper.Initialize(cfg =>
            {
                cfg.AddProfile<MajorProfile>();
                
            });
            Mapper.AssertConfigurationIsValid();//驗證所有的映射配置是否都正常
        }
    }
[DependsOn(
        typeof(AbpWebMvcModule),
        typeof(SIMSDataModule), 
        typeof(SIMSApplicationModule), 
        typeof(SIMSWebApiModule),
        typeof(AbpAutoMapperModule))]
   
    public class SIMSWebModule : AbpModule
    {
        public override void PreInitialize()
        {
            //Add/remove languages for your application
            Configuration.Localization.Languages.Add(new LanguageInfo("en", "English", "famfamfam-flag-england", true));
            Configuration.Localization.Languages.Add(new LanguageInfo("tr", "Türkçe", "famfamfam-flag-tr"));
            Configuration.Localization.Languages.Add(new LanguageInfo("zh-CN", "簡體中文", "famfamfam-flag-cn"));

            //Add/remove localization sources here
            Configuration.Localization.Sources.Add(
                new DictionaryBasedLocalizationSource(
                    SIMSConsts.LocalizationSourceName,
                    new XmlFileLocalizationDictionaryProvider(
                        HttpContext.Current.Server.MapPath("~/Localization/SIMS")
                        )
                    )
                );

            //Configure navigation/menu
            Configuration.Navigation.Providers.Add<SIMSNavigationProvider>();
        }

        public override void Initialize()
        {
            
        IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly());
            AutoMapperWebConfig.Configure();//一次性加載所有映射配置
            AreaRegistration.RegisterAllAreas();
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
        }
    }

   5.SIMS.WebApi層不需要做任何修改,DynamicApiControllerBuilper提供了建立所有應用層服務的方法比如:

DynamicApiControllerBuilder.ForAll<IApplicationService>(typeof(SIMSApplicationModule).Assembly, "app").Build(); //app 就是路由調用的名字

   5.1當然也可以通過DynamicApiControllerBuilder.For<IxxxAppService>("app").Build();語句來動態的出初始化。如:DynamicApiControllerBuilder.For<IMajorAppService>("app").Build();

   5.2根據以上配置,在上面的APPlication里面建立的IMajorAppService的訪問路由就是:/api/services/app/major

   5.3 可以通過單一服務腳本處理:http://localhost:6234/api/abpServiceProxies/Get?name=app/major,代碼樣式如:

(function(){

    var serviceNamespace = abp.utils.createNamespace(abp, 'services.app.major');

    serviceNamespace.getAll = function(ajaxParams) {
        return abp.ajax($.extend({
            url: abp.appPath + 'api/services/app/major/GetAll',
            type: 'POST',
            data: JSON.stringify({})
        }, ajaxParams));
    };

    serviceNamespace.insertorUpdate = function(input, ajaxParams) {
        return abp.ajax($.extend({
            url: abp.appPath + 'api/services/app/major/InsertorUpdate',
            type: 'POST',
            data: JSON.stringify(input)
        }, ajaxParams));
    };

    if(define && typeof define === 'function' && define.amd){
        define(function (require, exports, module) {
            return {
                getAll: serviceNamespace.getAll,
                insertorUpdate: serviceNamespace.insertorUpdate
            };
        });
    }

})();

 

  6.在SIMS.Controller里面可以訪問5的WebAPI接口,代碼:

(function () {
    var controllerId = 'app.views.show.show';
    angular.module('app').controller(controllerId, [
             '$scope', 'abp.services.app.major',   //abp.service.app.major要和5的js代碼里的ServiceNameSpace一致
             function ($scope, majorService) { //majorService是abp.service.app.major的major+Service組合成,一定要這么寫,不然報錯
                 var vm = this;
                 vm.major = { id: 0, majorName: '' };
                 vm.getAll = function () {
                     majorService.getAll().success(function (ajaxParams) {
                         vm.majorlist = ajaxParams;
                     });
                 }
                 
                 vm.InsertorUpdate = function () {
                     majorService.insertorUpdate({
                         Id: vm.major.id,
                         MajorName: vm.major.majorName
                     }).success(function () {
                         vm.major.majorName = '';
                         vm.getAll();
                     });
                 }
                 vm.getAll();
             }
    ]);
})();
<div ng-controller="app.views.show.show as vm">
    <table>
        <tr>
            <td>ID</td><td>Majortype</td>
        </tr>
        <tr ng-repeat="item in vm.majorlist">
            <td>{{item.id}}</td>
            <td>{{item.majorName}}</td>
        </tr>
    <tr>
        <td>
            majortype
        </td>
        <td>
            <input type="hidden" ng-model="vm.major.id" />
            <input type="text" ng-model="vm.major.majorName"/>
            <button ng-click="vm.InsertorUpdate()">add</button>
        </td>
    </tr>
    </table>
</div>
<script src="/api/abpServiceProxies/Get?name=app/major" type="text/javascript"></script>

 

在app.js里面添加路由

 app.config([
        '$stateProvider', '$urlRouterProvider',
        function($stateProvider, $urlRouterProvider) {
            $urlRouterProvider.otherwise('/');
            $stateProvider
                .state('home', {
                    url: '/',
                    templateUrl: '/App/Main/views/home/home.cshtml',
                    menu: 'Home' //Matches to name of 'Home' menu in SIMSNavigationProvider
                })
                .state('about', {
                    url: '/about',
                    templateUrl: '/App/Main/views/about/about.cshtml',
                    menu: 'About' //Matches to name of 'About' menu in SIMSNavigationProvider
                }).state('show', {
                    url: '/show',
                    templateUrl: '/App/Main/views/show/show.cshtml',
                    menu: 'show'
                });

        }
    ]);

 

ABP跨域問題

1、在Web Api 項目下安裝 Microsoft.AspNet.WebApi.Cors 包

Install-Package Microsoft.AspNet.WebApi.Cors

2、在Web Api 項目下的Module中添加如下兩行代碼。

var cors = new EnableCorsAttribute("*", "*", "*"); GlobalConfiguration.Configuration.EnableCors(cors);

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM