通常想从容器中获取对象,咱们都是经过构造方法获取对象,但有些条件不容许不能经过构造方法获取对象,咱们必须单独从容器中单首创建获取找个对象,这样咱们就不行把找个容器静态保存起来供全局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