首页 > 其他分享 > 手动获取IServiceProvider依赖注入的 服务实例

手动获取IServiceProvider依赖注入的 服务实例

时间:2022-11-23 11:00:39浏览次数:50  
标签:Task libraryContext serviceProvider 手动 实例 var IServiceProvider logger public

 手动获取IServiceProvider依赖注入的 服务实例
 
 Task.Run(() => {
            try
            {
                //Task里创建了新的IServiceScope
                using var scope = _scopeFactory.CreateScope();
                //通过IServiceScope创建具体实例
                LibraryContext dbContext = scope.ServiceProvider.GetService<LibraryContext>();
                var list = dbContext!.Informations.Where(i => i.IsDelete == 0).Take(100).ToList();
            }



Task.Run(() => {
            try
            {
                //Task里创建了新的IServiceScope
                using var scope = _serviceProvider.CreateScope();
                //通过IServiceScope创建具体实例
                LibraryContext dbContext = scope.ServiceProvider.GetService<LibraryContext>();
                var list = dbContext!.Informations.Where(i => i.IsDelete == 0).Take(100).ToList();
            }
            

[Route("api/[controller]/[action]")]
[ApiController]
public class InformationController : ControllerBase
{
    private readonly LibraryContext _libraryContext;
    private readonly IServiceProvider _serviceProvider;
    private readonly ILogger<InformationController> _logger;

    public InformationController(LibraryContext libraryContext, 
        IServiceProvider serviceProvider,
        ILogger<InformationController> logger)
    {
        _libraryContext = libraryContext;
        _serviceProvider = serviceProvider;
        _logger = logger;
    }

    [HttpGet]
    public string GetFirst()
    {
        var caseInfo = _libraryContext.Informations.Where(i => i.IsDelete == 0).FirstOrDefault();
        //这里直接使用了Task方式
        Task.Run(() => {
            try
            {
                //Task里创建了新的IServiceScope
                using var scope = _serviceProvider.CreateScope();
                //通过IServiceScope创建具体实例
                LibraryContext dbContext = scope.ServiceProvider.GetService<LibraryContext>();
                var list = dbContext!.Informations.Where(i => i.IsDelete == 0).Take(100).ToList();
            }
            catch (Exception ex)
            {
                _logger.LogError(ex.Message, ex);
            }
        });
        return caseInfo.Title;
    }
}

报错:
Cannot access a disposed object.
Object name: 'IServiceProvider'.


[Route("api/[controller]/[action]")]
[ApiController]
public class InformationController : ControllerBase
{
    private readonly LibraryContext _libraryContext;
    private readonly IServiceScopeFactory _scopeFactory;
    private readonly ILogger<InformationController> _logger;

    public InformationController(LibraryContext libraryContext, 
        IServiceScopeFactory scopeFactory,
        ILogger<InformationController> logger)
    {
        _libraryContext = libraryContext;
        _scopeFactory = scopeFactory;
        _logger = logger;
    }

    [HttpGet]
    public string GetFirst()
    {
        var caseInfo = _libraryContext.Informations.Where(i => i.IsDelete == 0).FirstOrDefault();
        //这里直接使用了Task方式
        Task.Run(() => {
            try
            {
                //Task里创建了新的IServiceScope
                using var scope = _scopeFactory.CreateScope();
                //通过IServiceScope创建具体实例
                LibraryContext dbContext = scope.ServiceProvider.GetService<LibraryContext>();
                var list = dbContext!.Informations.Where(i => i.IsDelete == 0).Take(100).ToList();
            }
            catch (Exception ex)
            {
                _logger.LogError(ex.Message, ex);
            }
        });
        return caseInfo.Title;
    }
}

//如果想获取根容器的实例则可以通过获取IServiceScopeFactory实例获取,最后请注意IServiceScope的释放问题。
微软给我们的建议是

注入一个IServiceScopeFactory以便在后台工作项中创建一个范围。
IServiceScopeFactory是一个单例对象。
在后台线程中创建一个新的依赖注入范围。
不引用控制器中的任何东西。
不从传入请求中捕获DbContext。
https://learn.microsoft.com/en-us/aspnet/core/performance/performance-best-practices?view=aspnetcore-6.0#do-not-capture-services-injected-into-the-controllers-on-background-threads
[HttpGet("/fire-and-forget-3")]
public IActionResult FireAndForget3([FromServices]IServiceScopeFactory serviceScopeFactory)
{
    _ = Task.Run(async () =>
    {
        await Task.Delay(1000);

        using (var scope = serviceScopeFactory.CreateScope())
        {
            var context = scope.ServiceProvider.GetRequiredService<ContosoDbContext>();
            context.Contoso.Add(new Contoso());
            await context.SaveChangesAsync();                                        
        }
    });

    return Accepted();
}


public void Configure(IApplicationBuilder app)
{
 ServiceLocator.Instance = app.ApplicationServices;
}
 
public static class ServiceLocator
{
 public static IServiceProvider Instance { get; set; }
}
 
 
public void DemoMethod()
{
 var demoService = ServiceLocator.Instance.GetService<IDemoService>();
}
注意:使用ServiceLocator.Instance.GetService()只能获取AddTransient和AddSingleton注入的对象,而不能获取AddScoped(请求生命周期内唯一)注入的对象,因为获取的对象和构造函数获取的不是同一个(即获取的对象没有共享),使用场景比如IUnitOfWork。
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
 
namespace Domain
{
 public class DemoService : IDemoService
 {
  private IUnitOfWork _unitOfWork;
 
  public DemoService (IHttpContextAccessor httpContextAccessor)
  {
   _unitOfWork = httpContextAccessor.HttpContext.RequestServices.GetService<IUnitOfWork>();
  }
 }
}
https://www.cnblogs.com/donchen/p/16484705.html



源文:https://www.cnblogs.com/wucy/p/16566495.html


  private readonly IServiceProvider _serviceProvider;

   public SomeService(IServiceProvider serviceProvider) {
      _serviceProvider = serviceProvider;
   }

 var eventBus = _serviceProvider.GetService(typeof(IEventBus)) as IEventBus;
https://www.codenong.com/50411466/

 

标签:Task,libraryContext,serviceProvider,手动,实例,var,IServiceProvider,logger,public
From: https://www.cnblogs.com/shy1766IT/p/16917610.html

相关文章