• 【Net】ABP框架学习之正面硬钢


    前言

    本文介绍另一种学习ABP框架的方法,该方法为正面硬钢学习法。。。

    我们不去官网下载模板,直接引用DLL,直接使用。

    WebApi项目创建

    首先创建一个WebApi项目,结构如下。

    然后Nuget搜索ABP,安装ABP框架。(我这里安装的是5.1.0,因为最高版本安装不上)

    在安装ABP前先检查当前安装的Microsoft.AspNet.WebApi版本,因为ABP5.1.0依赖的是WebApi的5.2.7,如果WebApi不是5.2.7,在Nuget包管理—程序包管理器控制台中输入Update-Package Microsoft.AspNet.WebApi -Version 5.2.7来升级一下。(Get-Package查看已安装包的信息)

    然后修改Global.asax,修改代码如下:

    using Abp.Web;
    using ABPWebApi;
    using System;
    using System.Web;
    [assembly: PreApplicationStartMethod(typeof(PreStarter), "Start")]
    namespace ABPWebApi
    {
        public class WebApiApplication : Abp.Web.AbpWebApplication<SdudentApiServiceModule>
        {
            protected override void Application_Start(object sender, EventArgs e)
            { 
                base.Application_Start(sender, e);
            } 
        }
        public static class PreStarter
        {
            public static void Start()
            {     //WebApiApplication.AbpBootstrapper.PlugInSources.AddToBuildManager();
            }
        }
    }

    这里WebApiApplication不再继承System.Web.HttpApplication,改为继承ABP框架下的Abp.Web.AbpWebApplication;因此原生框架提供的Application_Start不再需要,代码里重写了ABP的Application_Start,这样我们就找到了Application_Start,可以在启动时做自己想做的事情了。

    AbpWebApplication是个泛型,要求指定默认启动模块的类,这里我们先写上SdudentApiServiceModule,下面会创建这个类。

    在Global中,还使用PreApplicationStartMethod做了一些启动预处理,比如加载一些插件,当然也可以什么都不做。

    如果要加载插件或者做一些其他操作,则需要再引入ABP.WEB,因为一些配置的依赖库在这里,这里同样引用5.1.0版本。

    因为使用了ABP框架,所以我们不再需要微软提供的默认布局了,下面我们微软的默认布局文件夹删除;如下图:

    现在我们新建一个类库,创建一个SdudentApi模块,用来编写可以被HTTP访问的接口。

    创建完类库后,我们需要在类库里添加一个自定义类,来标记,这个类库是WebApi服务模块。

    创建SdudentApiServiceModule类,并继承AbpModule。

    很明显AbpModule在SdudentApi类库是未被引用的,所以我们要引用一下ABP的框架。

    因为这个模块是WebApi,所以我们直接引用Abp.Web.Api5.1.0就可以了。(由于Abp.Web.Api依赖于Abp,所以Abp也会被同时引入)

    现在我们编辑SdudentApiServiceModule类。

    因为继承了AbpModule,所以我们可以override它PreInitialize,Initialize,PostInitialize,Shutdown;它们分别是模块初始化前,中,后和关闭。(只有被加载和关闭时调用这些方法,调用API方法时,这些不触发)

    下面我们编写下SdudentApiServiceModule,代码如下:

    [DependsOn(typeof(Abp.WebApi.AbpWebApiModule))]
        public class SdudentApiServiceModule : AbpModule
        {
            public override void PreInitialize()
            {
                Configuration.Modules.AbpWeb().AntiForgery.IsEnabled = false;
                Configuration.Modules.AbpWebCommon().SendAllExceptionsToClients = true;  
            }
            public override void Initialize()
            {
                //按照约定,ABP自动注册所有 Repositories, Domain Services, Application Services, MVC 控制器和Web API控制器
                //ABP按照约定注册程序集,下面代码将告诉ABP要注册当前程序集。
                IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly());
                //动态ApiController创建需要在将当前程序集注册进ABP后,才可以调用
                //WebApi访问路径默认前缀api/services,Sdudent是我们追加的前缀,可以自定义,例如Sdudent/Task
                //外放成ApiController的服务需要继承ABP的IApplicationService接口,需要准守命名约定,这样才能被搜索到(服务命名约定:服务名+AppService,例如SearchSdudentAppService) 
                Configuration.Modules.AbpWebApi().DynamicApiControllerBuilder
                .ForAll<IApplicationService>(Assembly.GetAssembly(typeof(SdudentApiServiceModule)), "Sdudent").Build();  
            } 
            public override void PostInitialize()
            { 
            } 
            public override void Shutdown()
            {   
            }
        }

    首先我们为SdudentApiServiceModule添加依赖[DependsOn(typeof(Abp.WebApi.AbpWebApiModule))],这是因为,ABP都是通过Castle进行依赖控制反转实例化对象的,所以,在实例化SdudentApiServiceModule时,如果它依赖的类没有被装载,它就会报错,因为我们在写WebApi,所以很明显,我们依赖Abp.WebApi.AbpWebApiModule这个模块。

    PreInitialize:这里我们Http请求的简单配置,还可以继续配置,ABP配置很多。

    Initialize:这里将当前类装载进ABP,同时动态创建了ApiController。

    PostInitialize和Shutdown暂时无操作。


    现在我们创建服务(它们将被转换成ApiController)。

    创建接口ISearchSdudentAppService,代码如下:

    public interface ISearchSdudentAppService :  IApplicationService
        {
            [HttpGet]
            string GetSdudent();
        }

    注意接口方法需要加[HttpGet],不加的会被默认注册为Post,测试时会出现无法访问的问题。

    创建服务SearchSdudentAppService,代码如下:

    public class SearchSdudentAppService: ISearchSdudentAppService
        { 
            public string GetSdudent()
            {
                return "I am a Sdudent";
            }
        }

    SdudentApiServiceModule编写完成,现在我们运行项目测试一下。

     如上图,访问成功。

    Url解析:这里我们访问的URL是/api/services/Sdudent/SearchSdudent/GetSdudent。

    其中/api/services是默认前缀,Sdudent/是我们自定义前缀,SearchSdudent是Controler名,它是根据服务名来的,服务名减去约定名(SearchSdudentAppService-AppService),GetSdudent是Action名,就是服务里的方法名。


    跨域配置

    Nuget搜索Microsoft.AspNet.WebApi.Cors,安装与Microsoft.AspNet.WebApi相同版本号的Cors。

    SdudentApiServiceModule模块的PreInitialize方法里追加配置。

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

    Filter配置

    在SdudentApiServiceModule模块创建ExceptionFilter类,代码如下:

    public class ExceptionFilter : IExceptionFilter, ITransientDependency
    {
        public bool AllowMultiple => true; 
        public async Task ExecuteExceptionFilterAsync(HttpActionExecutedContext actionExecutedContext, CancellationToken cancellationToken)
        {
            await Task.Run(()=>
            {
    ​
                if (actionExecutedContext == null)
                {
    ​
                    return;
                }
                if (actionExecutedContext.Exception == null)
                {
                    return;
                }
                //记录actionExecutedContext.Exception
            }); 
        } 
    }

    在SdudentApiServiceModule类的PostInitialize里配置Fliter。

    public override void PostInitialize()
    {
        GlobalConfiguration.Configuration.Filters.Add(new ExceptionFilter());
    } 

    模块依赖

    依照上文,在创建一个TeacherApi模块,然后修改Global的启动模块为TeacherApiServiceModule,然后引入SdudentApi项目。

    然后编写TeacherApiServiceModule代码如下:

    [DependsOn(typeof(Abp.WebApi.AbpWebApiModule), typeof(SdudentApiServiceModule))]
    public class TeacherApiServiceModule : AbpModule
    {
        private readonly SdudentApiServiceModule _SdudentApiServiceModule;
        public TeacherApiServiceModule(SdudentApiServiceModule sdudentApiServiceModule)
        {
            _SdudentApiServiceModule = sdudentApiServiceModule;
        }
        public override void PreInitialize()
        {
            Configuration.Modules.AbpWeb().AntiForgery.IsEnabled = false;
            Configuration.Modules.AbpWebCommon().SendAllExceptionsToClients = true; 
        }
        public override void Initialize()
        { 
            IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly()); 
            Configuration.Modules.AbpWebApi().DynamicApiControllerBuilder
            .ForAll<IApplicationService>(Assembly.GetAssembly(typeof(TeacherApiServiceModule)), "Sdudent").Build(); 
        }
        public override void PostInitialize()
        {
            var ret =_SdudentApiServiceModule.GetSdudent();
            Console.WriteLine(ret);
        } 
        public override void Shutdown()
        {   
        }
    }

    如上代码所示,我们在DependsOn上追加SdudentApiServiceModule依赖,然后在TeacherApiServiceModule的构造函数里,使用SdudentApiServiceModule类型参数,然后运行时参数就会被实例化,并注入进来。

    现在我们访问TeacherApi的访问,把TeacherApiServiceModule模块调用起来,看下模块的PostInitialize里,是否成功调用了SdudentApiServiceModule模块的方法。

    如上图,依赖调用成功。

    Swagger配置

    Nuget搜索Swashbuckle.core。

    模块下添加函数

    private void ConfigureSwaggerUi()
    {
        Configuration.Modules.AbpWebApi().HttpConfiguration
            .EnableSwagger(c =>
            {
                c.SingleApiVersion("v1", "文档");
                c.ResolveConflictingActions(apiDescriptions => apiDescriptions.First());
            })
            .EnableSwaggerUi();
    }

    然后在Initialize()里调用该函数,配置完成。

    然后运行项目,输入swagger/ui/index,如下图:

    ----------------------------------------------------------------------------------------------------

    代码已经传到Github上了,欢迎大家下载。

    Github地址: https://github.com/kiba518/ApbWebApi

    ----------------------------------------------------------------------------------------------------

    注:此文章为原创,任何形式的转载都请联系作者获得授权并注明出处!
    若您觉得这篇文章还不错,请点击下方的推荐】,非常感谢!

    https://www.cnblogs.com/kiba/p/12524915.html

     

  • 相关阅读:
    .html(),.text()和.val()的差异总结:
    获取或设置checkbox radio select的值
    sublime 搜索时忽略文件夹
    转载------一小时包教会 —— webpack 入门指南
    转载--git教程
    转载--网站数据统计分析中的日志收集原理及其实现
    devexpress 安装及破解
    基于socket的客户端和服务端聊天简单使用 附Demo
    Ajax技术原理小结
    oracle 资源学习汇总
  • 原文地址:https://www.cnblogs.com/kiba/p/12524915.html
Copyright © 2020-2023  润新知