通常想從容器中獲取對象,咱們都是經過構造方法獲取對象,但有些條件不容許不能經過構造方法獲取對象,咱們必須單獨從容器中單首創建獲取找個對象,這樣咱們就不行把找個容器靜態保存起來供全局diaoygit
1、 簡單些一下步驟以下:(從某一個大神視頻或者代碼中學習到的,具體哪一個不記得了)github
1.先作一個構建對象的接口IEngine多線程
public interface IEngine { /// <summary> /// 構建一個實例 /// </summary> /// <typeparam name="T"></typeparam> /// <returns></returns> T Resolve<T>() where T : class; /// <summary> /// 構建類型 /// </summary> /// <param name="type"></param> /// <returns></returns> object Resolve(Type type); }
2.再構建一個引擎對象實現 IEngine接口app
public class GeneralEngine : IEngine { private IServiceProvider _serviceProvider; public GeneralEngine(IServiceProvider serviceProvider) { this._serviceProvider = serviceProvider; } /// <summary> /// 構建實例 /// </summary> /// <typeparam name="T"></typeparam> /// <returns></returns> public T Resolve<T>() where T : class { return _serviceProvider.GetService<T>(); } /// <summary> /// 構建類型 /// </summary> /// <param name="type"></param> /// <returns></returns> public object Resolve(Type type) { return _serviceProvider.GetService(type); } }
3.再建立一個保存容器的對象EnginContextide
public class EnginContext { private static IEngine _engine; /// <summary> /// /// </summary> /// <param name="engine"></param> /// <returns></returns> [MethodImpl(MethodImplOptions.Synchronized)] //多線程同時只能訪問一次 public static IEngine Initialize(IEngine engine) { if (_engine == null) _engine = engine; return _engine; } /// <summary> /// 當前引擎 /// </summary> public static IEngine Current { get { return _engine; } } }
4. 在Startup類ConfigureServices方法中加入學習
EnginContext.Initialize(new GeneralEngine(services.BuildServiceProvider()));
5.使用以下 ,不須要經過構造方法獲取對象了 ui
ILogger logger = EnginContext.Current.Resolve<ILogger<BaseController>>();
2、Nlog的做用和寫法我就不具體描述了,接下來主要說一下用這種方法獲取不到Nlog對象this
當經過 EnginContext.Initialize(new GeneralEngine(services.BuildServiceProvider()));這種方法生成引擎的時候spa
private ILogger<ValuesController> _logger; private ILogger<ValuesController> _GeneralEnginelogger; public ValuesController(ILogger<ValuesController> logger) { _logger = logger; _logger.LogInformation("構造方法獲取的對象日誌"); _GeneralEnginelogger = EnginContext.Current.Resolve<ILogger<ValuesController>>(); _GeneralEnginelogger.LogInformation("EnginContext方法獲取的對象日誌"); }
運行後 界面日誌以下:線程
並無發現[EnginContext方法獲取的對象日誌] 但仔細觀察控制檯界面是有信息的產生的
以上說明並無獲取nlog日誌對象,只是獲取到asp net core 自帶的日誌對象,調試能夠驗證,
剛開始發現這個文件感受比較莫名其妙,經過構造方法能夠獲取nlog對象,爲何經過引擎 services.BuildServiceProvider().GetService<>這個方法獲取不了對象呢;
最後發如今IApplicationBuilder對象有一個ApplicationServices屬性它的GetRequiredService也能夠獲取對象,將上述引擎改到Configure類中這樣就能夠了
EnginContext.Initialize(new GeneralEngine(services.BuildServiceProvider()));改爲以下
EnginContext.Initialize(new GeneralEngine(app.ApplicationServices));
運行截圖以下:
代碼以下:https://github.com/lxshwyan/QuartzDemo.git