标签:
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‘
});
}
]);
标签:
原文地址:http://www.cnblogs.com/shuajing/p/5449283.html