基於 abp vNext 和 .NET Core 開發博客項目 - 完善與美化,Swagger登場

来源:https://www.cnblogs.com/meowv/archive/2020/05/18/12909558.html
-Advertisement-
Play Games

上一篇文章(https://www.cnblogs.com/meowv/p/12896898.html)已經成功將博客項目跑起來了,那麼本篇主要是將之前遺留的問題解決,現在的代碼看起來可能還是比較混亂,有大量與之無關的代碼存在裡面,對於強迫症患者來說真的是零容忍。 在程式員界,總有一批強迫症患者,他 ...


上一篇文章(https://www.cnblogs.com/meowv/p/12896898.html)已經成功將博客項目跑起來了,那麼本篇主要是將之前遺留的問題解決,現在的代碼看起來可能還是比較混亂,有大量與之無關的代碼存在裡面,對於強迫症患者來說真的是零容忍。

在程式員界,總有一批強迫症患者,他們希望自己寫的代碼看起來儘量的完美無瑕疵。

完善與美化

直奔主題,首先將各項目層的項目文件(.csproj)打開,格式化一下,沒有引用<Import Project="..\..\common.props" />這句代碼的也加一下,這裡其實就是將公共屬性拿出來,沒什麼特殊的。

common.props中的代碼也非常簡單,主要是禁用當開啟輸出XML的時候沒有給代碼進行summary註釋產生的警告,其實這些大可不必為之折騰,不影響項目的成功運行。如果您覺得沒啥必要,完全可以跳過此小節看最後。

.Application

.Application層現在只引用Volo.Abp.Identity.Application包,和依賴.Application.Caching.Application.Contracts.Domain.Shared三個項目。

//Meowv.Blog.Application.csproj
<Project Sdk="Microsoft.NET.Sdk">

  <Import Project="..\..\common.props" />

  <PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Volo.Abp.Identity.Application" Version="2.7.0" />
    
    <ProjectReference Include="..\Meowv.Blog.Application.Caching\Meowv.Blog.Application.Caching.csproj" />
    <ProjectReference Include="..\Meowv.Blog.Application.Contracts\Meowv.Blog.Application.Contracts.csproj" />
    <ProjectReference Include="..\Meowv.Blog.Domain.Shared\Meowv.Blog.Domain.Shared.csproj" />
  </ItemGroup>

</Project>

.Application.Caching

.Application.Caching層看名字就知道,我準備用它來處理緩存,這裡會用到兩個包,Volo.Abp.CachingMicrosoft.Extensions.Caching.Redis

不管三七二十一,新建一個模塊類MeowvBlogApplicationCachingModule.cs,依賴於AbpCachingModule和我們的MeowvBlogDomainModule模塊(此時還沒添加)

using Volo.Abp.Caching;
using Volo.Abp.Modularity;

namespace Meowv.Blog.Application.Caching
{
    [DependsOn(
        typeof(AbpCachingModule)
        // ...
    )]
    public class MeowvBlogApplicationCachingModule : AbpModule
    {
        public override void ConfigureServices(ServiceConfigurationContext context)
        {
            base.ConfigureServices(context);
        }
    }
}
//Meowv.Blog.Application.Caching.csproj
<Project Sdk="Microsoft.NET.Sdk">

  <Import Project="..\..\common.props" />

  <PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
  </PropertyGroup>
  
  <ItemGroup>
    <PackageReference Include="Microsoft.Extensions.Caching.Redis" Version="2.2.0" />
    <PackageReference Include="Volo.Abp.Caching" Version="2.7.0" />
    
    <ProjectReference Include="..\Meowv.Blog.Application.Contracts\Meowv.Blog.Application.Contracts.csproj" />
    <ProjectReference Include="..\Meowv.Blog.Domain.Shared\Meowv.Blog.Domain.Shared.csproj" />
    <ProjectReference Include="..\Meowv.Blog.ToolKits\Meowv.Blog.ToolKits.csproj" />
  </ItemGroup>

</Project>

.Application.Contracts

刪掉裡面所有文件,.Application.Contracts層我不准備按照abp那樣來做,此層我只想用來放我們的傳輸對象(DTO),添加項目引用Domain.Shared,同時開啟輸出XML文件到我們.HttpApi.Hosting

輸出XML很簡單,在 Visual Studio 中對著項目 右鍵=>屬性=>生成=>輸出,然後選擇XML文檔文件,預設為一個物理路徑,我們將其改為相對路徑..\Meowv.Blog.HttpApi.Hosting\Meowv.Blog.Application.Contracts.xml,XML輸出到.HttpApi.Hosting層。

也可以直接修改項目文件實現,如下

//Meowv.Blog.Application.Contracts.csproj
<Project Sdk="Microsoft.NET.Sdk">

  <Import Project="..\..\common.props" />

  <PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
  </PropertyGroup>

  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
    <DocumentationFile>..\Meowv.Blog.HttpApi.Hosting\Meowv.Blog.Application.Contracts.xml</DocumentationFile>
  </PropertyGroup>

  <ItemGroup>
    <ProjectReference Include="..\Meowv.Blog.Domain.Shared\Meowv.Blog.Domain.Shared.csproj" />
  </ItemGroup>

</Project>

.Domain

.Domain層為我們的實體領域模型,不需要引用其它層,只添加包Volo.Abp.Identity.Domain,同時也輸出一下XML文件,XML文件的作用後續Swagger會用的。

//Meowv.Blog.Domain.csproj
<Project Sdk="Microsoft.NET.Sdk">

  <Import Project="..\..\common.props" />

  <PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
  </PropertyGroup>

  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
    <DocumentationFile>..\Meowv.Blog.HttpApi.Hosting\Meowv.Blog.Domain.xml</DocumentationFile>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Volo.Abp.Identity.Domain" Version="2.7.0" />

    <ProjectReference Include="..\Meowv.Blog.Domain.Shared\Meowv.Blog.Domain.Shared.csproj" />
  </ItemGroup>

</Project>

刪掉此層所有文件,不要忘了添加模塊類,MeowvBlogDomainModule.cs,它依賴AbpIdentityDomainModule模塊

using Volo.Abp.Identity;
using Volo.Abp.Modularity;

namespace Meowv.Blog.Domain
{
    [DependsOn(typeof(AbpIdentityDomainModule))]
    public class MeowvBlogDomainModule : AbpModule
    {

    }
}

此時上面.Application.Caching中可以將MeowvBlogDomainModule加上了。

//MeowvBlogApplicationCachingModule.cs
...
    [DependsOn(
        typeof(AbpCachingModule),
        typeof(MeowvBlogDomainModule)
    )]
    public class MeowvBlogApplicationCachingModule : AbpModule
    {
        ...
    }
...

.Domain.Shared

.Domain.Shared層相當於.Domain的一個擴展一樣,這裡放一下項目用到的枚舉、公共常量等內容,需要引用我們的.Domain項目

<Project Sdk="Microsoft.NET.Sdk">

  <Import Project="..\..\common.props" />

  <PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <ProjectReference Include="..\Meowv.Blog.Domain\Meowv.Blog.Domain.csproj" />
  </ItemGroup>

</Project>

還是要新增一個模塊類MeowvBlogDomainSharedModule.cs,它依賴AbpIdentityDomainSharedModule模塊

//MeowvBlogDomainSharedModule.cs
using Volo.Abp.Identity;
using Volo.Abp.Modularity;

namespace Meowv.Blog.Domain
{
    [DependsOn(typeof(AbpIdentityDomainModule))]
    public class MeowvBlogDomainModule : AbpModule
    {
    }
}

.EntityFrameworkCore

.EntityFrameworkCore層同樣的,先刪掉預設生成的文件。它主要是集成了EF Core,自定義倉儲。詳細可以看看abp文檔:https://docs.abp.io/zh-Hans/abp/latest/Repositories

它支持多種資料庫 MySQL、SqlServer、PostgreSql、Sqlite等,如果你有用到MongoDB,則需要新建一個項目,單獨實現。可以看官方文檔,有時間可以分享具體方法,本項目用不到。https://docs.abp.io/zh-Hans/abp/latest/MongoDB

為了方便大家,我把以上4種主流資料庫都集成到項目中,添加包Volo.Abp.EntityFrameworkCore.MySQL.PostgreSql.Sqlite.SqlServer,同時引用.Domain.Shared項目

//Meowv.Blog.EntityFrameworkCore.csproj
<Project Sdk="Microsoft.NET.Sdk">

  <Import Project="..\..\common.props" />

  <PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
  </PropertyGroup>
  
  <ItemGroup>
    <PackageReference Include="Volo.Abp.EntityFrameworkCore.MySQL" Version="2.7.0" />
    <PackageReference Include="Volo.Abp.EntityFrameworkCore.PostgreSql" Version="2.7.0" />
    <PackageReference Include="Volo.Abp.EntityFrameworkCore.Sqlite" Version="2.7.0" />
    <PackageReference Include="Volo.Abp.EntityFrameworkCore.SqlServer" Version="2.7.0" />

    <ProjectReference Include="..\Meowv.Blog.Domain.Shared\Meowv.Blog.Domain.Shared.csproj" />
  </ItemGroup>

</Project>

新建一個模塊類MeowvBlogFrameworkCoreModule.cs,依賴MeowvBlogDomainModule和資料庫模塊

//MeowvBlogFrameworkCoreModule.cs
using Meowv.Blog.Domain;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore.MySQL;
using Volo.Abp.EntityFrameworkCore.PostgreSql;
using Volo.Abp.EntityFrameworkCore.Sqlite;
using Volo.Abp.EntityFrameworkCore.SqlServer;
using Volo.Abp.Modularity;

namespace Meowv.Blog.EntityFrameworkCore
{
    [DependsOn(
        typeof(MeowvBlogDomainModule),
        typeof(AbpEntityFrameworkCoreModule),
        typeof(AbpEntityFrameworkCoreMySQLModule),
        typeof(AbpEntityFrameworkCoreSqlServerModule),
        typeof(AbpEntityFrameworkCorePostgreSqlModule),
        typeof(AbpEntityFrameworkCoreSqliteModule)
    )]
    public class MeowvBlogFrameworkCoreModule : AbpModule
    {
        public override void ConfigureServices(ServiceConfigurationContext context)
        {

        }
    }
}

.EntityFrameworkCore.DbMigrations

.EntityFrameworkCore.DbMigrations層主要做資料庫遷移,用code-first方式創建資料庫表,先刪掉預設生成的文件,目前還用不上,後面講。

.ToolKits

.ToolKits層是我們手動創建的項目,我主要用它來包裝一些擴展方法,公共的工具類。

Swagger登場

做.net core開發的,相信Swagger的使用大家應該都很熟悉了,不做過多的介紹,今天只先將其用上看看效果。

我單獨為Swagger新建了一個項目Meowv.Blog.Swagger,其實大可不必,直接寫在.HttpApi.Hosting中也是一樣的。

添加Volo.Abp.AspNetCoreSwashbuckle.AspNetCore包,引用實體層.Domain

//Meowv.Blog.Swagger.csproj
<Project Sdk="Microsoft.NET.Sdk">

  <Import Project="..\..\common.props" />

  <PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Volo.Abp.AspNetCore" Version="2.7.0" />
    <PackageReference Include="Swashbuckle.AspNetCore" Version="5.4.1" />

    <ProjectReference Include="..\Meowv.Blog.Domain\Meowv.Blog.Domain.csproj" />
  </ItemGroup>

</Project>

添加模塊類MeowvBlogSwaggerModule.cs,依賴MeowvBlogDomainModule模塊,並且重寫ConfigureServicesOnApplicationInitialization方法,不知道這是什麼的,可以看文檔:https://docs.abp.io/zh-Hans/abp/latest/Module-Development-Basics

然後新建一個擴展類MeowvBlogSwaggerExtensions.cs,編寫兩個擴展方法AddSwaggerUseSwaggerUI

AddSwagger方法中引用我們的XML文件,配置介面的名稱版本以及描述信息,在UseSwaggerUI方法中使用SwaggerUI,代碼如下:

//MeowvBlogSwaggerExtensions.cs
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.OpenApi.Models;
using System;
using System.IO;

namespace Meowv.Blog.Swagger
{
    public static class MeowvBlogSwaggerExtensions
    {
        public static IServiceCollection AddSwagger(this IServiceCollection services)
        {
            return services.AddSwaggerGen(options =>
            {
                options.SwaggerDoc("v1", new OpenApiInfo
                {
                    Version = "1.0.0",
                    Title = "我的介面啊",
                    Description = "介面描述"
                });

                options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, "Meowv.Blog.HttpApi.xml"));
                options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, "Meowv.Blog.Domain.xml"));
                options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, "Meowv.Blog.Application.Contracts.xml"));
            });
        }

        public static void UseSwaggerUI(this IApplicationBuilder app)
        {
            app.UseSwaggerUI(options =>
            {
                options.SwaggerEndpoint($"/swagger/v1/swagger.json", "預設介面");
            });
        }
    }
}

隨後便可以在模塊MeowvBlogDomainModule中引用了

//MeowvBlogSwaggerModule.cs
using Meowv.Blog.Domain;
using Microsoft.AspNetCore.Builder;
using Volo.Abp;
using Volo.Abp.Modularity;

namespace Meowv.Blog.Swagger
{
    [DependsOn(typeof(MeowvBlogDomainModule))]
    public class MeowvBlogSwaggerModule : AbpModule
    {
        public override void ConfigureServices(ServiceConfigurationContext context)
        {
            context.Services.AddSwagger();
        }

        public override void OnApplicationInitialization(ApplicationInitializationContext context)
        {
            context.GetApplicationBuilder().UseSwagger().UseSwaggerUI();
        }
    }
}

最後在.HttpApi.Hosting層的的啟動模塊中引用一下。

//MeowvBlogHttpApiHostingModule.cs
...
    [DependsOn(
       typeof(AbpAspNetCoreMvcModule),
       typeof(AbpAutofacModule),
       typeof(MeowvBlogHttpApiModule),
       typeof(MeowvBlogSwaggerModule),
       typeof(MeowvBlogFrameworkCoreModule)
    )]
    public class MeowvBlogHttpApiHostingModule : AbpModule
    {
        ...
    }
...

Ctrl + Shift + B生成解決方案,Ctrl+F5打開 .../swagger/index.html 看看效果,上面有一個坑沒有填,不知道大家發現了沒有,Meowv.Blog.HttpApi.xml沒有生成,啟動是是會報錯的,大家按照之前的方法自行生成XML即可。

1

棒!預期已經達到了。Swagger之所以想單獨創建一個項目是因為還涉及到很多內容,如介面分組、JWT授權、還有Swagger文檔描述信息的Filter等。

項目中還剩下.BackgroundJobs層沒有處理,此層準備集成Hangfire做一個定時任務處理的,後面會慢慢用起來的。

現在再回頭看看,項目是不是很清爽? 沒有亂七八糟的東西,有的只是我們需要的。

此時的層級目錄,以供參考。

2

項目中可能有許多不是很合理的地方,請酌情參考。因為大佬們都不願意出來分享,所以我們渣渣只能做到這種程度,如果有錯誤歡迎指正,謝謝。

開源地址:https://github.com/Meowv/Blog/tree/blog_tutorial


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 微信機器人的實現有三種:web,app和exe。其中web很多賬號受限登錄不了,而hook app的話需要使用xposed則會封號,所以現在大部分機器人都是基於PC微信。 先實現一下最基本的機器人的功能:接收消息和發送消息。找相關call請看:https://blog.csdn.net/qq_384 ...
  • 我看到 "這篇文章" 之後自己嘗試了一下還是找不到對應的call,畢竟沒有學習過逆向,只是因為一時興起想逆向一下微信。 找到關鍵CALL 不過我找到了一個投機取巧的辦法:因為已經知道了微信的二維碼圖片是PNG格式的,而PNG有一個通用的文件頭,如下 我們可以利用這個找到記憶體中的二維碼圖片,然後對它下 ...
  • 目標:在win10系統上安裝linux虛擬機,並ssh登陸。 第一步:安裝虛擬機 在實際工作中,通常需要多台伺服器,這時候通過虛擬軟體,將一臺主機分割模擬成多個伺服器是很好的選擇。 在這裡我使用VirtualBox虛擬軟體來創建虛擬機,官方網址:https://www.virtualbox.org/ ...
  • ​ 如果想看更多技術好書,可以關註微信公眾號【程式員書單】作者黃小斜,目前是阿裡Java工程師,業餘時間廣泛讀書,在公眾號里除了分享程式員必讀的技術書籍之外,也會推薦很多關於個人成長、投資理財等方面的書籍。你煩惱的每個問題,書中都有答案。 在這裡,我們將為你推薦幫助程式員以及互聯網從業者自我提升的各 ...
  • 啟言:每個函數定義都有鏈接器可識別的獨一無二的編譯後的函數名稱 種類:C 語言鏈接性、C++ 語言鏈接性,可能有如下的編譯器翻譯 spiff( int ) _spiff // C spiff( int ) _spiff_i // C++ (函數重載) spiff(double, double) _s ...
  • SunnyUI.Net, 基於 C# .Net WinForm 開源控制項庫、工具類庫、擴展類庫、多頁面開發框架 Blog: https://www.cnblogs.com/yhuse Gitee: https://gitee.com/yhuse/SunnyUI GitHub: https://git ...
  • 過程很簡單,傳遞ViewModel到附加屬性,附加屬性引發相關事件和取消事件,從而引發VM中的委托。 修正版本2 2020年5月19日 07點03分 徹底一模一樣了,和之前寫的。 不過更順了 添加內容 public class AttachModel: Animatable { public sta ...
  • 最近公司很多業務都要求上雲,雲上的資料庫購買了mysql(估計是應為便宜吧),所以我用abp框架開發的應用都要逐步切換到mysql。經過一陣摸索踩坑,總算是切換成功了,所以先記錄下方便後續切換使用,也順便分享給有需要的朋友。 一、集成MySQL 其實集成mysql主要是參照官方文檔進行就可以了(官方 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...