(2)ASP.NET Core 依賴關係注入(服務)

1.前言

面向對象設計(OOD)裏有一個重要的思想就是依賴倒置原則(DIP),並由該原則牽引出依賴注入(DI)、控制反轉(IOC)及其容器等老生常談的概念,初學者很容易被這些概念搞暈(包括我在內),在學習Core依賴注入服務以前,下面讓咱們先了解下依賴倒置原則(DIP)、依賴注入(DI)、控制反轉(IOC)等概念,而後再深刻學習Core依賴注入服務。設計模式

2.依賴倒置原則(DIP)

高層模塊不依賴於低層模塊的實現,而低層模塊依賴於高層模塊定義的接口。通俗來說,就是高層模塊定義接口,低層模塊負責實現。框架

2.依賴注入(DI)

2.1依賴(D)

當一個類須要另外一個類協做來完成工做的時候就產生了依賴。
示例1:ide

public class MyDependency
{
    public MyDependency()
    {
    }
    public Task WriteMessage(string message)
    {
        Console.WriteLine($"MyDependency.WriteMessage called. Message: {message}");
        return Task.FromResult(0);
    }
}
public class IndexModel : PageModel
{
    MyDependency _dependency = new MyDependency();
    public void OnGet()
    {
        _dependency.WriteMessage("IndexModel.OnGet created this message.");
    }
}

由上述代碼能夠看到IndexModel 模塊輸出消息必需要實例化MyDependency模塊,也就是說IndexModel 模塊業務的實現必須依賴於MyDependency模塊,這就是依賴函數

2.2 注入(I)

根據DIP設計原則:高層模塊不依賴於低層模塊的實現,而低層模塊依賴於高層模塊定義的接口,因此咱們在這裏定義一個接口供高層模塊調用,底層模塊負責實現。
示例2:學習

public interface IMyDependency
{
    Task WriteMessage(string message);
}
public class MyDependency: IMyDependency
{
    public MyDependency()
    {
    }
    public Task WriteMessage(string message)
    {
        Console.WriteLine($"MyDependency.WriteMessage called. Message: {message}");
        return Task.FromResult(0);
    }
}
public class IndexModel : PageModel
{
    IMyDependency _dependency = new MyDependency();
    public void OnGet()
    {
        _dependency.WriteMessage("IndexModel.OnGet created this message.");
    }
}

從上述代碼能夠看到當咱們調用IndexModel 模塊OnGetAsync方法的時候,是經過IMyDependency接口實例化MyDependency類去實現其方法內容的,這叫控制正轉。可是Master說,咱們不該該建立MyDependency類,而是讓調用者給你傳遞,因而你經過構造函數讓外界把這兩個依賴給你。
示例3:ui

public interface IMyDependency
{
    Task WriteMessage(string message);
}
public class MyDependency : IMyDependency
{
    private readonly ILogger<MyDependency> _logger;
    public MyDependency(ILogger<MyDependency> logger)
    {
        _logger = logger;
    }
    public Task WriteMessage(string message)
    {
        _logger.LogInformation(
            "MyDependency.WriteMessage called. Message: {MESSAGE}",
            message);
        return Task.FromResult(0);
    }
}
public class IndexModel : PageModel
{
    private readonly IMyDependency _dependency;
    public IndexModel(IMyDependency dependency)
    {
        _dependency = dependency;
    }
    public void OnGet()
    {
        _dependency.WriteMessage("IndexModel.OnGet created this message.");
    }
}

從上述代碼能夠看到把依賴的建立丟給第三方系統(例:Autofac,Unity容器),也叫控制反轉(IOC)容器。本身只負責使用,其它人丟給你依賴的這個過程理解爲注入。也叫控制反轉(IOC)。注意,框架內部ILogger接口已注入,無需手動再從新注入。this

2.3 IOC容器

IOC容器能夠看做是負責統一管理依賴關係的地方。常見有Autofac,Unity。
容器只要負責兩件事情:
●綁定服務與實例之間的關係
●獲取實例,並對實例進行管理(建立與銷燬)spa

3.依賴倒置原則(DIP)與控制反轉(IOC)的區別

DIP是一種軟件設計原則,它僅僅告訴你高低層模塊之間應該如何依賴,可是它並無告訴咱們如何解除相互依賴模塊的耦合。而IOC則是一種軟件設計模式,它告訴咱們該如何解除模塊的耦合,它爲相互依賴的組件提供抽象,將依賴(低層模塊)對象的得到交給第三方系統(例:Autofac,Unity容器)來控制,即依賴對象不在被依賴模塊的類中直接經過new來獲取設計

4.NET Core依賴注入(DI)服務

通過上面描述,你們應該應該對依賴倒置原則(DIP)、依賴注入(DI)、控制反轉(IOC)這幾個概念有必定了解對吧。在.NET Core中DI的核心分爲兩個組件:IServiceCollection和 IServiceProvider。
●IServiceCollection負責註冊
●IServiceProvider負責提供實例
下面讓咱們來學習下NET Core是怎麼依賴注入(DI)服務。
第一步:使用接口來實現依賴反轉。定義 IMyDependency 服務。日誌

public interface IMyDependency
{
    Task WriteMessage(string message);
}

第二步:定義IMyDependency 服務的實現類MyDependency。

public class MyDependency : IMyDependency
{
    private readonly ILogger<MyDependency> _logger;
    public MyDependency(ILogger<MyDependency> logger)
    {
        _logger = logger;
    }
    public Task WriteMessage(string message)
    {
        _logger.LogInformation(
            "MyDependency.WriteMessage called. Message: {MESSAGE}",
            message);
        return Task.FromResult(0);
    }
}

第三步:把IMyDependency 服務註冊到服務容器中。

public void ConfigureServices(IServiceCollection services)
{
//註冊將服務生命期的範圍限定爲單個請求的生命期,下節再來聊服務生命期
    services.AddScoped<IMyDependency, MyDependency>();
}

第四步:把服務注入到使用它的類的構造函數中。在HomeController裏面調用IndexModel.OnGet方法輸出WriteMessage消息。

public class IndexModel : PageModel
{
    private readonly IMyDependency _dependency;
    public IndexModel(IMyDependency dependency)
    {
        _dependency = dependency;
    }
    public void OnGet()
    {
        _dependency.WriteMessage("IndexModel.OnGet created this message.");
    }
}
private readonly IMyDependency _iMyDependency;
public HomeController(IMyDependency iMyDependency)
{
    _iMyDependency = iMyDependency;
}
public IActionResult Index()
{
    IndexModel _IndexModel = new IndexModel(_iMyDependency);
    _IndexModel.OnGet();
    return View();
}

WriteMessage日誌消息以下:

5.默認服務容器替換

下面咱們未來演示內置容器怎麼替換爲其餘容器示例,好比替換第三方 Autofac容器,咱們須要在Startup.ConfigureServices方法裏面註冊Autofac容器,具體代碼以下:

public IServiceProvider ConfigureServices(IServiceCollection services)
{
    // Add Autofac
    var containerBuilder = new ContainerBuilder();
    containerBuilder.RegisterModule<DefaultModule>();
    containerBuilder.Populate(services);
    var container = containerBuilder.Build();
    return new AutofacServiceProvider(container);
}

這裏須要注意的是若是須要使用第三方容器,Startup.ConfigureServices 必須返回 IServiceProvider。而後自定義一個模塊類配置依賴關係,具體代碼以下:

public class DefaultModule : Module
{
    protected override void Load(ContainerBuilder builder)
    {
        builder.RegisterType<CharacterRepository>().As<ICharacterRepository>();
    }
}

應用程序在運行時,使用 Autofac 來解析類型,並注入依賴關係。


參考文獻:
在ASP.NET Core依賴注入

相關文章
相關標籤/搜索