• BodeAbp服务端介绍


    BodeAbp服务端只提供api,绝大部分api通过abp的动态WebApi机制提供,原理可以参考这篇文章:http://www.cnblogs.com/1zhk/p/5418694.html
    与业务相关的api写在模块内部,这样服务端几乎都不需要有Controller了,目前整个项目只有“登录”和“文件上传”有Controller代码,最大化的减少业务模块与系统的耦合,也更方便业务模块的加载/卸载。
     
    服务端目录结构:

    BodeAbp.Frame:abp框架

    BodeAbp.Modules:业务模块

    BodeAbp.Plugins:插件

    BodeAbp.Samples:示例

    业务模块目录结构:
    BodeAbp.Product:功能模块程序集
    Localization:本地化资源文件夹
    Providers:模块权限、菜单、设置项文件夹
    Attributes:子功能文件夹(这里是商品属性)
    Domain:领域层,存放聚合根、领域服务、值对象等。
    Dtos:存放数据传输对象
    ModelConfigs:存放Model配置类
    SeedActions:存放种子数据(创建数据库或迁移数据库时添加到即数据库的数据)
    ...AppServices:应用程序服务,业务实现,是向外提供webapi的基础
     
    Module中代码:
    using System.Reflection;
    using Abp.EntityFramework.Default;
    using Abp.Localization.Dictionaries;
    using Abp.Localization.Dictionaries.Xml;
    using Abp.Modules;
    using BodeAbp.Product.Providers;
    
    namespace BodeAbp.Product
    {
        /// <summary>
        /// 产品模块
        /// </summary>
        public class BodeAbpProductModule : AbpModule
        {
            /// <summary>
            /// 版本号
            /// </summary>
            public const string CurrentVersion = "0.1.0";
    
            /// <summary>
            /// 初始化前执行
            /// </summary>
            public override void PreInitialize()
            {
                Configuration.Localization.Sources.Add(
                    new DictionaryBasedLocalizationSource(
                        BodeAbpProductConsts.LocalizationSourceName,
                        new XmlEmbeddedFileLocalizationDictionaryProvider(
                            Assembly.GetExecutingAssembly(),
                            "BodeAbp.Product.Localization.Source"
                            )
                        )
                    );
    
                Configuration.Settings.Providers.Add<BodeAbpProductSettingProvider>();
                Configuration.Navigation.Providers.Add<BodeAbpProductNavigationProvider>();
                Configuration.Authorization.Providers.Add<BodeAbpProductAuthorizationProvider>();
    
                DefaultDbContextInitializer.Instance.MapperAssemblies.Add(Assembly.GetExecutingAssembly());
            }
    
            /// <summary>
            /// 初始化执行
            /// </summary>
            public override void Initialize()
            {
                IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly());
            }
    
            /// <summary>
            /// 初始化后执行
            /// </summary>
            public override void PostInitialize()
            {
                base.PostInitialize();
            }
        }
    }
    View Code
    关于abp中的模块机制,可以参考文章:http://www.cnblogs.com/farb/p/ABPModuleSystem.html
    DefaultDbContextInitializer类是BodeAbp默认的数据库初始化类,可以仿造其实现将不同模块中的实体注册到不同的DbContext来达到分库的目的。DefaultDbContext默认读取webconfig中Default的连接字符串。
     
    IApplicationService中代码:
    using Abp.Application.Services;
    using System.ComponentModel;
    using Abp.Application.Services.Dto;
    using BodeAbp.Product.Attributes.Dtos;
    using System.Collections.Generic;
    using System.Threading.Tasks;
    
    namespace BodeAbp.Product.Attributes
    {
        /// <summary>
        ///  属性 服务
        /// </summary>
        [Description("属性接口")]
        public interface IAttributesAppService : IApplicationService
        {
            #region 属性模版
    
            /// <summary>
            /// 获取 属性模版分页
            /// </summary>
            /// <param name="input"></param>
            /// <returns></returns>
            Task<PagedResultOutput<GetAttributeListOutput>> GetAttributePagedList(QueryListPagedRequestInput input);
    
            /// <summary>
            /// 获取 属性模版详情
            /// </summary>
            /// <param name="id">id</param>
            /// <returns></returns>
            Task<GetAttributeOutput> GetAttribute(int id);
    
            /// <summary>
            /// 添加 属性模版
            /// </summary>
            /// <param name="input"></param>
            /// <returns></returns>
            Task CreateAttribute(CreateAttributeInput input);
    
            /// <summary>
            /// 更新 属性模版
            /// </summary>
            /// <param name="input"></param>
            /// <returns></returns>
            Task UpdateAttribute(UpdateAttributeInput input);
    
    
            /// <summary>
            /// 删除 属性模版
            /// </summary>
            /// <param name="input"></param>
            /// <returns></returns>
            Task DeleteAttribute(List<IdInput> input);
    
            #endregion
    
            #region 属性值
    
            /// <summary>
            /// 获取 属性值分页
            /// </summary>
            /// <param name="input"></param>
            /// <returns></returns>
            Task<PagedResultOutput<GetAttributeOptionListOutput>> GetAttributeOptionPagedList(QueryListPagedRequestInput input);
    
            /// <summary>
            /// 获取 属性值详情
            /// </summary>
            /// <param name="id">id</param>
            /// <returns></returns>
            Task<GetAttributeOptionOutput> GetAttributeOption(int id);
    
            /// <summary>
            /// 添加 属性值
            /// </summary>
            /// <param name="input"></param>
            /// <returns></returns>
            Task CreateAttributeOption(CreateAttributeOptionInput input);
    
            /// <summary>
            /// 更新 属性值
            /// </summary>
            /// <param name="input"></param>
            /// <returns></returns>
            Task UpdateAttributeOption(UpdateAttributeOptionInput input);
    
    
            /// <summary>
            /// 删除 属性值
            /// </summary>
            /// <param name="input"></param>
            /// <returns></returns>
            Task DeleteAttributeOption(List<IdInput> input);
    
            #endregion
    
            #region 分类
            
            /// <summary>
            /// 获取 分类分页
            /// </summary>
            /// <param name="input"></param>
            /// <returns></returns>
            Task<PagedResultOutput<GetProductClassifyListOutput>> GetClassifyPagedList(QueryListPagedRequestInput input);
    
            /// <summary>
            /// 获取 分类详情
            /// </summary>
            /// <param name="id">id</param>
            /// <returns></returns>
            Task<GetProductClassifyOutput> GetClassify(int id);
    
            /// <summary>
            /// 添加 分类
            /// </summary>
            /// <param name="input"></param>
            /// <returns></returns>
            Task CreateClassify(CreateProductClassifyInput input);
    
            /// <summary>
            /// 更新 分类
            /// </summary>
            /// <param name="input"></param>
            /// <returns></returns>
            Task UpdateClassify(UpdateProductClassifyInput input);
    
    
            /// <summary>
            /// 删除 分类
            /// </summary>
            /// <param name="classifyId">分类Id</param>
            /// <returns></returns>
            Task DeleteClassify(int classifyId);
    
            #endregion
        }
    }
    View Code

    加载模块:

    在WebApi项目的Module类中加载模块,代码如下:
    using System.Reflection;
    using System.Web.Http;
    using Abp.Application.Services;
    using Abp.Configuration.Startup;
    using Abp.Modules;
    using Abp.WebApi;
    using Abp.WebApi.Controllers.Dynamic.Builders;
    using Swashbuckle.Application;
    using System.Linq;
    using System.Web.Http.Cors;
    using BodeAbp.Zero;
    using System;
    using WebDemo.WebApi.Swagger;
    using BodeAbp.Activity;
    using BodeAbp.Product;
    
    namespace WebDemo.WebApi
    {
        [DependsOn(
            typeof(AbpWebApiModule)
            , typeof(WebDemoCoreModule)
            , typeof(BodeAbpZeroModule)
            , typeof(BodeAbpActivityModule)
            , typeof(BodeAbpProductModule))]
        public class WebDemoWebApiModule : AbpModule
        {
            public override void Initialize()
            {
                IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly());
    
                DynamicApiControllerBuilder
                    .ForAll<IApplicationService>(typeof(WebDemoCoreModule).Assembly, "app")
                    .Build();
    
                DynamicApiControllerBuilder
                    .ForAll<IApplicationService>(typeof(BodeAbpZeroModule).Assembly, "zero")
                    .Build();
    
                DynamicApiControllerBuilder
                    .ForAll<IApplicationService>(typeof(BodeAbpActivityModule).Assembly, "activity")
                    .Build();
    
                DynamicApiControllerBuilder
                    .ForAll<IApplicationService>(typeof(BodeAbpProductModule).Assembly, "product")
                    .Build();
    
    
                Configuration.Modules.AbpWebApi().HttpConfiguration.Filters.Add(new HostAuthenticationFilter("Bearer"));
    
                var cors = new EnableCorsAttribute("*", "*", "*");
                GlobalConfiguration.Configuration.EnableCors(cors);
                
                ConfigureSwaggerUi();
            }
    
            private void ConfigureSwaggerUi()
            {
                Configuration.Modules.AbpWebApi().HttpConfiguration
                    .EnableSwagger(c =>
                    {
                        c.SingleApiVersion("v1", "WebDemo.WebApi");
                        //c.OperationFilter<AuthorizationOperationFilter>();
                        c.DocumentFilter<ApplicationDocumentFilter>();
                        c.IncludeXmlComments(GetXmlCommentsPath(typeof(WebDemoCoreModule)));
                        c.IncludeXmlComments(GetXmlCommentsPath(typeof(BodeAbpZeroModule)));
                        c.IncludeXmlComments(GetXmlCommentsPath(typeof(BodeAbpActivityModule)));
                        c.IncludeXmlComments(GetXmlCommentsPath(typeof(BodeAbpProductModule)));
                        c.ResolveConflictingActions(apiDescriptions => apiDescriptions.First());
                    })
                    .EnableSwaggerUi(c => {
                        c.CustomAsset("index", typeof(WebDemoWebApiModule).Assembly, "WebDemo.WebApi.Swagger.index.html");
                        c.InjectStylesheet(typeof(WebDemoWebApiModule).Assembly, "WebDemo.WebApi.Swagger.theme-flattop.css");
                        c.InjectJavaScript(typeof(WebDemoWebApiModule).Assembly, "WebDemo.WebApi.Swagger.translator.js");
                    });
            }
    
            private static string GetXmlCommentsPath(Type moduleType)
            {
                return string.Format(@"{0}\bin\{1}.XML", AppDomain.CurrentDomain.BaseDirectory, moduleType.Assembly.GetName().Name);
            }
        }
    }
    View Code
     
    浏览Api:

    确保webconfig中数据库连接正确,直接运行项目,浏览器访问:http://localhost:61759/swagger/ui/index#/,效果图如下:


    BodeAbp采用了swagger展示api,关于swagger的配置参考WebApi项目的Module类中的ConfigureSwaggerUi方法。
  • 相关阅读:
    Java 常见异常种类
    Spring3.2+mybatis3.2+Struts2.3整合配置文件大全
    Java中的基本类型和引用类型变量的区别
    【git】Git 提示fatal: remote origin already exists 错误解决办法
    【Java集合】Java中集合(List,Set,Map)
    POJ3322-经典的游戏搜索问题
    程序人生[流程图]
    不使用中间变量交换两个数
    做人要低调,别把自己太当回事
    【转】嵌套子控件设计时支持
  • 原文地址:https://www.cnblogs.com/liuyh/p/5673219.html
Copyright © 2020-2023  润新知