asp.net core不經過構造方法從容器中獲取對象及解決經過這種方法NLog獲取對象失敗的問題

     通常想從容器中獲取對象,咱們都是經過構造方法獲取對象,但有些條件不容許不能經過構造方法獲取對象,咱們必須單獨從容器中單首創建獲取找個對象,這樣咱們就不行把找個容器靜態保存起來供全局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

相關文章
相關標籤/搜索