zoukankan      html  css  js  c++  java
  • NET Core DI 手动获取注入对象

    NET Core DI 手动获取注入对象

    ASP.NET Core DI 一般使用构造函数注入获取对象,比如在ConfigureServices配置注入后,通过下面方式获取:

    private IValueService _valueService;
    
    public ValueController(IValueService valueService)
    {
        _valueService = valueService;
    }
    

    那如果手动获取注入对象呢?

    第一种获取方式(有时会获取不到,不推荐使用):

    var services = new ServiceCollection();
    var provider = services.BuildServiceProvider();
    
    var _valueService = provider.GetService<IValueService>();
    

    第二种获取方式(推荐使用):

    public void Configure(IApplicationBuilder app)
    {
        ServiceLocator.Instance = app.ApplicationServices;
    }
    
    public static class ServiceLocator
    {
        public static IServiceProvider Instance { get; set; }
    }
    
    
    public void SomeRandomMethod()
    {
        var valueService = ServiceLocator.Instance.GetService<IValueService>();
    
        // Do something with service
    }
    

    补充:需要注意的是,使用ServiceLocator.Instance.GetService<T>();,只能获取AddTransientAddSingleton注入的对象,而不能获取AddScoped(请求生命周期内唯一)注入的对象,不是不能获取,而是获取的和构造函数获取的不是相同对象,也就是说获取的对象没有共享,使用场景比如IUnitOfWork

    那怎么手动获取请求生命周期内的注入对象呢?方法如下:

    using Microsoft.AspNetCore.Http;
    using Microsoft.Extensions.DependencyInjection;
    
    namespace Sample.Domain
    {
        public class SampleDomainService : IDomainService
        {
            private IUnitOfWork _unitOfWork;
    
            public SampleDomainService(IHttpContextAccessor httpContextAccessor)
            {
                _unitOfWork = httpContextAccessor.HttpContext.RequestServices.GetService<IUnitOfWork>();
            }
        }
    }
    

    IHttpContextAccessor接口在Microsoft.AspNetCore.Http.AbstractionsNuget 程序包下。

    参考资料:

    控制器相关中:HttpContext来获取实例

    HttpContext下有一个RequestedService同样可以用来获取实例对象

    IUserDAL userDAL = HttpContext.RequestServices.GetService(typeof(IUserDAL)) as IUserDAL;

    方法二:使用静态类来获取依赖注入对象

    新增加一个类(注意不是内部类不然都不好直接获取了):

    public static class ServiceLocator
    {
       public static IServiceProvider Instance { get; set; }
    }
    

    然后在Configure中去赋值一下即可:

    使用的时候就可以直接用了

    ConfigureServices

    有时间我们可以会做一点初始化的操作,需要在这里获取

    var provider = services.BuildServiceProvider();
    IArticleDAL userDAL = provider.GetService<IArticleDAL>(
    );
     

    注意:如果这里你用了ef,并且ef用了依赖注入获取,在ConfigureServices中获取时需要放到ef配置下面

    Configure

    IArticleDAL articleDAL = app.ApplicationServices.GetService(typeof(IArticleDAL)) as IArticleDAL;

    注意如果你需要获取的对象里边依赖的对象使用了Scope方式注入这样获取会报错:

    Cannot resolve 'XX.IArticleDAL' from root provider because it requires scoped service 'XX.CNBLOGContext'.
    

    需要这样获取

    //手动获取依赖注入对象
    IServiceScope serviceScope = app.ApplicationServices.CreateScope();
    IArticleDAL articleDAL2 = serviceScope.ServiceProvider.GetService<IArticleDAL>();

    但是:

    能通过 CreateScope 来正常 获取使用,为什么要用AddScope的方式注入?(反问)

    使用 AddScope 为了解决当前请求的生命周期内一些特殊的对象,下面介绍不使用 CreateScope ,而在当前上下文中来获取 实例

    作者:Leo_wl
             
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
    版权信息
  • 相关阅读:
    【Ionic+AngularJS 开发】之『个人日常管理』App(一)
    [热拔插] 轻量级Winform插件式框架
    Electron开发
    Cordova+Ionic之坑
    Unity学习笔记
    【树结构数据同步】公司部门—通讯录数据同步
    java enum用法
    Java中哈希表(Hashtable)是如何实现的
    注意for循环中变量的作用域
    BI-日期维度表-SQL SERVER
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/15728500.html
Copyright © 2011-2022 走看看