日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

ASP.NET Core中为指定类添加WebApi服务功能

發布時間:2023/12/4 asp.net 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ASP.NET Core中为指定类添加WebApi服务功能 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

POCO Controller是?ASP.NET Core?中的一個特性,雖然在2015年剛發布的時候就有這個特性了,可是大多數開發者都只是按原有的方式去寫,而沒有用到這個特性。其實,如果利用這個特性進行稍微封裝后,用在SOA架構中Service層的場景中是極其便利的。這篇文章主要就是說我最近在學習使用開源AOP庫AspectCore寫WebApi動態代理客戶端的時候,實現為普通類無添加WebApi服務的過程。

POCO控制器簡介

POCO控制器就是ASP.NET Core項目中所有帶有Controller后綴的類、或者標記了[Controller]特性的類,雖然沒有像模版項目中那樣繼承自Controller類,也會被識別為控制器,擁有跟普通控制器一樣的功能,像下面這段代碼中,兩個類都會被識別成控制器:

  • public class PocoController

  • {

  • ? ?public IActionResult Index()

  • ? ?{

  • ? ? ? ?return new ContentResult() { Content = Hello from POCO controller! };

  • ? ?}

  • }

  • [Controller]

  • public class Poco

  • {

  • ? ?public IActionResult Index()

  • ? ?{

  • ? ? ? ?return new ContentResult() { Content = Hello from POCO controller! };

  • ? ?}

  • }

  • POCO控制器原理

    其實,在ASP.NET Core中,已經不像舊版本的 ASP.NET WebApi 那樣,通過ControllerFactory來創建Controller,多虧于ASP.NET Core一脈相承的IoC框架?Microsoft.Extensions.DependencyInjection,ASP.NET Core中的內部實現變得更優雅。其中POCO控制器的核心原理就在IApplicationFeatureProvider<ControllerFeature>這個接口的實現ControllerFeatureProvider。

    通過aspnet/Mvc項目的Github源碼倉庫中查詢得知,Mvc里把Controller、ViewComponent、TagHelper、Views等組件定義為特性(Feature),如ControllerFeature,特性里就存放了應用中被識別為相組件的類型的集合,如如ControllerFeature中就存放了所有Controller類型。IApplicationFeatureProvider<ControllerFeature>這個接口是用來給MVC框架提供控制器類型識別的接口,當把這個接口的實現注冊到服務配置中,就能為其中識別的類型提供控制器功能。

    ControllerFeatureProvider是這個接口的默認實現,其中有一個方法IsController(TypeInfo typeInfo)的功能就是判斷某類型是否為控制器的。而接口方法PopulateFeature(IEnumerable<ApplicationPart> parts,ControllerFeature feature)則為把傳入的 “Mvc應用部分(ApplicationPart,大概是指Mvc的作用程序集)”中的類型都一一判斷,如果是控制器,那么就加入控制器特性對象中。

    實現自定義判斷規則

    通過上面的剖析,我們就知道要實現自定義的控制器判斷規則,只需要重寫ControllerFeature類或者重新實現IApplicationFeatureProvider<ControllerFeature>接口,但是由于PopulateFeature不是虛方法或抽象方法,所以不能被重寫,那么只能重新寫一個類來實現IApplicationFeatureProvider<ControllerFeature>接口了。為了兼容原來規則,我把原來的規則照搬過來,復制了IsController的方法(開源的好處),并且在PopulateFeature中加入了自己的規則。先貼代碼,避免篇幅過長,IsController方法的實現就直接鏈接到源碼了:

  • internal class ServiceControllerFeatureProvider : IApplicationFeatureProvider<ControllerFeature>

  • {

  • ? ?private const string ControllerTypeNameSuffix = "Controller";

  • ? ?private readonly IEnumerable<Type> ServiceTypes;

  • ? ?public ServiceControllerFeatureProvider(IEnumerable<Type> ServiceTypes)

  • ? ?{

  • ? ? ? ? ? ?this.ServiceTypes = ServiceTypes;

  • ? ?}

  • ? ?public void PopulateFeature(IEnumerable<ApplicationPart> parts, ControllerFeature feature)

  • ? ?{

  • ? ? ? ?foreach (var type in Reflection.CurrentAssembiles.SelectMany(o => o.DefinedTypes))

  • ? ? ? ?{

  • ? ? ? ? ? ?if (IsController(type) || ServiceTypes.Any(o => type.IsClass && o.IsAssignableFrom(type)) && !feature.Controllers.Contains(type))

  • ? ? ? ? ? ?{

  • ? ? ? ? ? ? ? ? ? ?feature.Controllers.Add(type);

  • ? ? ? ? ? ?}

  • ? ? ? ?}

  • ? ?}

  • ? ?protected bool IsController(TypeInfo typeInfo)

  • ? ?{

  • ? ? ? ?//...

  • ? ?}

  • }

  • 上面代碼的原理,是按照我的框架的需求來改寫的,構造方法傳入的參數ServiceTypes是定義了服務方法的接口的類型,接口和對應實現類似于以下代碼,這些代碼可以寫在一個.NET Core控制臺項目中。

  • public interface ITestService

  • {

  • ? ?string Test(string name);

  • }

  • [Route("test")]

  • public class TestService : ITestService

  • {

  • ? ?[Route("{name}"), HttpGet]

  • ? ?public string Test(string name)

  • ? ?{

  • ? ? ? ?return "Hello " + name;

  • ? ?}

  • }

  • 其中TestService類就是會被識別為控制器的類,但是接口和實現是可以分開在不同程序集的。通過原本ControllerFeatureProvider類中PopulateFeature方法的parts參數中的類型是不包括除了引用了Mvc的程序集的其它程序集的,所以我這里用自己實現的類型掃描類Reflection中的CurrentAssembiles靜態變量來獲取當前應用程序的所有引用的(自己創建的項目)程序集的,具體實現的代碼在我的框架[Shriek]的源碼中。

    配置自定義規則

    現在,我們擁有了自定義控制器識別規則ServiceControllerFeatureProvider,那么,怎么配置到Mvc中呢?又要去翻源碼了!在MvcCoreMvcBuilderExtensions.cs擴展類中,有一個IMvcBuilder的擴展方法ConfigureApplicationPartManager(IMvcCoreBuilder也有這樣的擴展方法),它的參數是傳入ApplicationPartManager參數的委托,而ApplicationPartManager中有一個FeatureProviders屬性,用來存儲所有IApplicationFeatureProvider實例,會在應用第一次運行的時候,循環這些“特性提供器”提供所有上面提到的MVC特性。所以,只要我們在這里添加我們自定義的控制器特性提供器,MVC框架內部就能識別我們的指定的類型為控制器,并為他們添加控制器的相關功能。

    設計有點繞,那么我們用代碼來實現:

  • //示例直接new ServiceCollection對象,下面有完整的能運行的示例代碼。

  • var services = new ServiceCollection();

  • services.AddMvcCore()

  • ? ? ? ?.ConfigureApplicationPartManager(manager =>

  • ? ? ? ?{

  • ? ? ? ? ? ?var featureProvider = new ServiceControllerFeatureProvider(typeof(ITestService));

  • ? ? ? ? ? ?manager.FeatureProviders.Add(featureProvider);

  • ? ? ? ?});

  • 看看效果

    現在,在TestService類所在項目文件中引入以下Nuget包(沒錯,運行一個webapi只需要兩個Nuget包):

  • ? ?<PackageReference Include="Microsoft.AspNetCore.Hosting" Version="2.0.0" />

  • ? ?<PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.0.0" />

  • 然后在控制臺程序的入口文件Program.cs的Main方法中寫入一下代碼:

  • internal class Program

  • {

  • ? ?public static void Main(string[] args)

  • ? ?{

  • ? ? ? new WebHostBuilder()

  • ? ? ? ? ? ?.UseKestrel()

  • ? ? ? ? ? ?.UseUrls("http://localhost:8080")

  • ? ? ? ? ? ?.ConfigureServices(services =>

  • ? ? ? ? ? ?{

  • ? ? ? ? ? ? ? ?services.AddMvcCore()

  • ? ? ? ? ? ? ? ?.ConfigureApplicationPartManager(manager =>

  • ? ? ? ? ? ? ? ?{

  • ? ? ? ? ? ? ? ? ? ?var featureProvider = new ServiceControllerFeatureProvider(typeof(ITestService));

  • ? ? ? ? ? ? ? ? ? ?manager.FeatureProviders.Add(featureProvider);

  • ? ? ? ? ? ? ? ?});

  • ? ? ? ? ? ?})

  • ? ? ? ? ? ?.Configure(app => app.UseMvc())

  • ? ? ? ? ? ?.Build()

  • ? ? ? ? ? ?.Start();

  • ? ?}

  • }

  • 一切編譯通過后,點擊運行,在瀏覽器中訪問”http://localhost:8080/test/elderjames”,如果看到返回了“Hello elderjames”,那么就大功告成啦!


    總結

    這篇文章中主要介紹了通過實現IApplicationFeatureProvider<ControllerFeature>接口實現設置指定類型為WebApi控制器的方法。

    在接下來的文章中,我會介紹如何從接口獲取自定義特性標簽,實現從接口獲得mvc特性,使得接口和實現類都不依賴MVC庫的方法,只要在接口中以標記特性的方式定義了路由和http方法,實現類的操作就都按照接口的路由和http方法去提供WebApi服務,最后還要介紹使用功能強大的.NTE Core開源AOP框架AspectCore實現的動態代理客戶端,注冊以上所說的接口,即可獲得可以調用對應的WebApi服務。這些工作的源碼可以在我的框架示例項目中運行,大家有興趣可以看看效果。


    總結

    以上是生活随笔為你收集整理的ASP.NET Core中为指定类添加WebApi服务功能的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。