今天來為大家介紹如何在 json 檔案中配置依賴注入。
在以前的ASP.NET 4+ (MVC,Web Api,Owin,SingalR等)時候,都是提供了專有的接口以供使用第三方的依賴注入組件,比如我們常用的會使用Autofac、Untiy 、String.Net 等,這些第三放依賴注入元件基本上都提供了一套配置注入或配置生命週期的方式,除了直接配置到類別裡面之外,還提供了要么使用xml 文件,要么使用json 等,那麼在新的ASP.NET Core 中微軟已經預設的給我們提供了一個依賴注入的功能,我們就不再需要藉助於第三方元件來實現依賴注入了,但是有時候我們想在設定檔中來配置依賴注入,微軟本身的DI 元件並沒有給我們一個可供配置的文件,那麼我們就需要自己來實現這個配置項的功能。個人覺得其主要使用場景是一些在編譯時無法確定實現的,需要動態修改實現的地方。
下面就來看看應該如何來做這件事情吧。
Getting Started
首先,在應用程式中我們創建一個接口,以供DI使用:
public interface IFoo { string GetInputString(string input); }
然後,添加一個 IFoo 接口的實現Foo
public class Foo : IFoo { public string GetInputString(string input) { return $"输入的字符串为:{ input }"; } }
public void ConfigureServices(IServiceCollection services) { services.Add(new ServiceDescriptor(serviceType: typeof(IFoo), implementationType: typeof(Foo), lifetime: ServiceLifetime.Transient)); }
介面和它的實作加入到Startup.cs 檔案中的ConfigureServices方法中,ConfigureServices 主要是用來配置依賴注入服務的。然後透過此方法提供的ISerciceCollection介面參數注入 Services。
"Logging": { "IncludeScopes": false, "LogLevel": { "Default": "Debug", "System": "Information", "Microsoft": "Information" } }, "DIServices": [ { "serviceType": "[namesapce].IFoo", "implementationType": "[namesapce].Foo", "lifetime": "Transient" } ] }
這裡,我們使用到了 IServiceCollection 裡面的 Add 方法,增加一個生命週期為瞬態的 IFoo 的實作。瞬態就是在每次請求的時候都會建立一個Foo的實例。
以上是預設微軟為我們提供的添加依賴注入的方法,下面我們來看看怎麼來改造成我們需要的使用 json 檔案的方式。
使用 json 文件配置 DI
當我們使用json文件配置依賴注入的時候,可以選擇新建一個json文件,也可以直接使用 appsettings.json 文件。現在我們就直接在 appsettings.json 檔案中加入關於DI的配置了。
appsettings.json
using Microsoft.Extensions.DependencyInjection; using Newtonsoft.Json; using Newtonsoft.Json.Converters; public class Service { public string ServiceType { get; set; } public string ImplementationType { get;set; } [JsonConverter(typeof(StringEnumConverter))] public ServiceLifetime Lifetime { get; set; } }
首先,新增一個名為「DIServices」 的陣列節點,陣列中包含一個或多個配置service的對象,serviceType代表服務介面的類型,implementationType介面的實作,lifetime 初始化實例的生命週期。
注意:設定檔中的類型必須為全名稱,即包含命名空間。
接下來,新增一個和Json檔案設定項相對應的一個service類,這裡我們需要使用 Newtonsoft 這個json庫。
public void ConfigureServices(IServiceCollection services) { //services.Add(new ServiceDescriptor(serviceType: typeof(IFoo), // implementationType: typeof(Foo), // lifetime: ServiceLifetime.Transient)); var jsonServices = JObject.Parse(File.ReadAllText("appSettings.json"))["DIServices"]; var requiredServices = JsonConvert.DeserializeObject<List<Service>>(jsonServices.ToString()); foreach (var service in requiredServices) { services.Add(new ServiceDescriptor(serviceType: Type.GetType(service.ServiceType), implementationType: Type.GetType(service.ImplementationType), lifetime: service.Lifetime)); } }
然後需要改造一下ConfigureServices,在 ConfigureServices 中讀取配置的 json檔案即可。
public class HomeController : Controller { private readonly IFoo _foo; public HomeController(IFoo foo) { _foo = foo; } public IActionResult About() { ViewData["Message"] = _foo.GetInputString("Your application description page."); return View(); } }
然後我們測試一下是否是可用的。
測試
打開 HomeController.cs ,新增註入項:
rrreee在 HomeController的構造函數新增IFoo接口,然後在 About 的Action中使用。
運行程序,打開頁面,點擊 About標籤總結
以上即為在 ASP.NET Core 中配置依賴注入到json文件中,這只是一個簡單的實例,不要用在生產環境中。在實際的專案中你還需要處理關於讀取配置異常情況,服務是否存在的異常情況,生命週期等等這些問題。