前言目前在开发abp电商模块,打算做一步,写一步,算是对自己的记录,主要是参考nopcommoner 并结合abp模块开发 知识都是连贯的,如果你熟悉asp.net core 3.x、abp(非vNext) 并且需要做电商功能,也许可以做个参考。即使不做电商,可能里面的其它功能也可以作为参考,如:如何开发abp模块、如何集成简单的微信功能(小程序登录、小程序支付)、通用字典模块、等等... 如果不熟悉asp.net core或abp,那建议还是补充基础知识后再说 如果你是专注电商的.neter,建议用nopcommerce,它是一个成熟完善的.net开源电商 本篇说说搭建电商模块开发环境 资源
建立电商模块项目abp的模块就是个dll+一个特殊的类(其中包含生命周期方法),具体概念请参考官方文档 我这里说的电商模块是指的功能模块,按abp的分层方式分为:
木有提供UI部分,因为是前后单分离的(WebAdmin是基于JQuery的纯静态网站) 可以看到结构与abp默认项目模板保持一致
XXX.Core与abp模型项目模板一致,它用来定义实体类、领域服务、领域事件、仓储接口 等。它是一个dll,也是一个独立的abp模块 可以看到所有东东还是原来的配方,如果你熟悉abp 几乎不用思考。 本篇主要讲商城模块环境搭架,所以下面只是简单说说正在做的一些具体功能 Catalogue/ItemsEntity:是已经在做的“商品上架信息”的实体类,里面包含:商品基本信息、上架信息(是否热卖,是否新品、上架开始/结束时间等)、价格信息(原价、优惠价、等.),后续会陆续添加其它电商业务相关实体,订单、会员啥的... Common/BXJGShopDictionaryEntity:电商模块单独的“通用字典”功能,比如支付方式、配送方式将来很多下拉框数据都使用这个,它是它是通过我们之前说的通用树模块来实现的。 Customer:顾客功能,它与abp的用户是做一对一关联,可以发现CustomerEntity<TUser>使用的泛型,这样将来你在引入商城模块时需要提供你自己的用户类型。整个商城功能可能会存在大量这种泛型的设计,目的是让模块与主程序分离。 Sale:中是跟销售相关的功能,核心的就是订单咯,后续会细讲 XXX.EFCore这个是对应abp中的XXX.EntityFrameworkCore模块,是用来定义电商业务中数据操作的,也称为仓储实现层。但是由于abp已经提供了一个通用的泛型仓储实现,因此这个类库中基本上看不到啥东西,除非有特殊情况才需要专门定义。 另一个重要作用是用来定义EF映射配置,因为决定所有实体采用ef api的方式来定义映射。其中ModelBuilderExt用来定义扩展方法,方便将来调用方一次性配置商城系统中的EF映射。在你的主程序的DbContext做如下配置: 1 protected override void OnModelCreating(ModelBuilder modelBuilder) 2 { 3 base.OnModelCreating(modelBuilder); 4 //扫描并应用商城模块中的ef映射 5 modelBuilder.ApplyConfigurationBXJGShop<User>(); 6 } XXX.Applicatiom商城模块应用服务层,同时它也是一个abp模块。
以“商品上架信息ItemEntity”为例感受下在XXX.Shop.Core中定义实体商城里肯定包含很多商品咯,它的实体定义在这里:源码 在XXX.Shop.Core中定义商品管理相关权限在xxx.Shop.EFCore中定义EF映射配置目前源码里针对商品信息的映射没有定义,因为使用api映射是后来决定的,不过有“订单”的映射文件可以参考。然后修改ModelBuilderExt,添加映射类,参考Order的设计 在xxx.Shop.Application中定义应用服务定义DTO、IAppService、AppService这个就是abp老套路,特别注意就是泛型的定义,目的之前说过,为了实现商城模块独立于主程序。参考源码。 主程序如何引入?1、主程序的EF中的DbContext配置 ![]() 1 #region 注册商城模块中的实体 2 public virtual DbSet<BXJGShopDictionaryEntity> BXJGShopDictionaries { get; set; } 3 public virtual DbSet<ItemEntity> BXJGShopItems { get; set; } 4 public virtual DbSet<CustomerEntity<User>> BXJGShopCustomers { get; set; } 5 public virtual DbSet<OrderEntity<User>> BXJGShopOrders { get; set; } 6 #endregion 7 8 public ZLJDbContext(DbContextOptions<ZLJDbContext> options) 9 : base(options) 10 { } 11 12 protected override void OnModelCreating(ModelBuilder modelBuilder) 13 { 14 base.OnModelCreating(modelBuilder); 15 16 //扫描并应用商城模块中的ef映射 17 modelBuilder.ApplyConfigurationBXJGShop<User>(); 18 } 2、主程序的Core/AuthorizationProvider配置商品管理的权限 ![]() 1 public class ZLJAuthorizationProvider : AuthorizationProvider 2 { 3 GeneralTreeModuleConfig cfg; 4 public ZLJAuthorizationProvider(GeneralTreeModuleConfig cfg) 5 { 6 this.cfg = cfg; 7 } 8 public override void SetPermissions(IPermissionDefinitionContext context) 9 { 10 var admin = context.CreatePermission(PermissionNames.Administrator, L("Administrator")); 11 //{codegenerator} 12 #region 商城 13 BXJGShopAuthorizationProvider.SetPermissions(admin); 14 #endregion 15 #region 资产管理 3、主程序的应用层中提供应用服务类,目的是指定商城管理服务需要的泛型 ![]() 1 public class ItemAppService : ItemAppService<Tenant, User, Role, TenantManager, UserManager> 2 { 3 public ItemAppService(IRepository<ItemEntity, long> repository) : base(repository) 4 { 5 } 6 } 4、主程序的Web.Core注册商城模块的动态api功能 ![]() 1 Configuration.Modules.AbpAspNetCore().CreateControllersForAppServices(typeof(BXJGShopApplicationModule).Assembly/*,"bxjgshop"*/); 最后整个设计尽量做到模块分离,主要还是参考abp zero的思路,它让你去提供User类,使用UserManager时也需要提供TUser,最后达到模块独立的效果、方便扩展,你可以实现自己的User添加扩展字段。 如何做到模块可扩展性呢?有几种思路,刚才说的模块内部大量使用泛型和抽象类,让模块的调用方(比如我们的主程序)可以通过继承的方式来进行扩展。 后面再考虑吧,万里长征第一步才开始~希望不会烂尾....
|
|