asp.net core-自定義service


asp.net core 結構

先看如下一張圖,虛線的黑框是我們的asp.net core程序,外部通過nginx實現反向代理接收http request和response。

內部是一個內置的web服務器Kestrel和web host主機(繼承自IHost),web host主機內部是我們的代碼,最內部運行的是帶有一個個中間件的管道。

下面是啟動的流程,創建一個IHostBuilder, 然后配置WebHostBuilder的相關配置(比如監聽端口,日志,kestrel或者其他的配置),然后通過Build方法來創建IHost。這時候會調用StartUp的ConfigureService(該方法用於注入服務),然后調用Ihost的Run方法來啟動,框架這時會自動調用Startup.Configure方法(該方法用於配置管道的中間件)。

Kestrel的兩種使用,kestrel是一個高效的,但功能簡單的內置web服務器,所以它一般會跟其他web服務器搭配使用。

 

 

 

 

 

IWebHostBuilder 配置

下面通過配置url來展示顯示各種方式的運行優先級,下面按優先級從低到高描述下4種配置形式

1. 通過環境變量配置

如圖,通過配置LaunchSettings.json中的applicationUrl可以設置ip和端口,這個會自動在下面生成ASPNETCORE_URLS標簽。

 

 

 

2. 通過編碼配置

 

3. 通過應用配置

注意圖中的urls標簽,這個是通過應用配置。另一個ASPNETCORE_URLS是屬於環境變量配置,凡是ASPNET開頭的配置都是環境變量配置。

 

 

4. 通過命令行配置

命令行啟動的時候有2種情況,第一種直接在項目根目錄通過dotnet run運行,后面配置端口如下圖

 

 第二種是通過publish之后生成了dll,如圖通過dotnet命令直接運行dll

 

 

優先級的意思是,假如同時配置了以上4種,那么最終監聽的端口以最后一種命令行的形式,比如9000或者7999.

自定義Service

依賴注入和控制反轉相信大家一定不會陌生,任何技術的出現都不是偶然,它必定是為順應時代而生。隨着項目越來越復雜,代碼量越來越多,那么代碼之間的耦合性就會越多,這個時候IOC容器應運而生。

控制反轉是指有一個第三方的容器,它將負責管理你需要的對象,你不再需要創建和管理你想要的對象類以及它的依賴,把創建以及生命周期的管理統統交給他。你只需要專心實現自己的功能。

依賴注入就是把你的類包括它的依賴注入到容器,然后再需要的地方通過某種方式直接拿到(可以是構造函數,接口,特性,setter)。

這一切的目的就是為了實現松耦合,可維護以及可測試。

asp.net core就有這么一個容器IServiceCollection(namespace是DependencyInjection,還有很多其他的依賴注入框架Unity,Autofac,Ninject,它們都是屬於.net的,功能比DependencyInjection更加強大)

asp.net core 提供了3種方式注入

// 創建單例
services.AddSingleton();
// 創建瞬時service,每次請求實例,容器都會new一個新的實例
services.AddTransient();
// 作用域,線程單例,在同一個線程里只創建一次。
services.AddScoped();

 

好了說了這么多,進入正題,如何優雅的實現自定義service

我們可以發現,asp.net core的源碼,所有的注入服務基本都是不帶參數,並且是通過lambda表達式來實現配置。

這里我們通過1個例子來展示下,我們的需求是注入2個類實現,但是它們的接口是一樣得,我們需要調用者通過不同的配置來調用不同的實例。

Interface和實現類就不寫了,下面寫MessageService的builder類,用於注入2個實現類

public class MessageServiceBuilder
{
    private IServiceCollection serviceCollection;

    public MessageServiceBuilder(IServiceCollection services)
    {
        serviceCollection = services;
    }

    public void UseEmail()
    {
        ServiceCollection.AddSingleton<IMessageService, EmailService>();
    }

    public void UseSms()
    {
        ServiceCollection.AddSingleton<IMessageService, SmsService>();
    }
}

下面就是核心了,創建一個IServiceCollection的擴展類,然后傳入一個參數是MessageServiceBuilder的Action,該Action在Startup中根據所需要的對象,調用特定的方法實現注入,然后執行這個Action。

public static class MessageServiceExtension
{
    public static void AddMessage(this IServiceCollection services, Action<MessageServiceBuilder> configure)
    {
        var builder = new MessageServiceBuilder(services);
        configure(builder);
    }
}
services.AddMessage(builder => builder.UseSms());

lambda讓c#成為了最優雅的語言,沒有之一。

這也是源碼的實現方式,另附上.net core源碼,https://github.com/dotnet/core


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM