ASP.NET Core DI手動で注入対象を取得


ASP.NET Core DIは、一般に、ConfigureServicesで構成された注入後、以下のようにして取得対象にコンストラクション関数注入を使用する.
private IValueService _valueService;

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

手動で注入オブジェクトを取得したら?
1つ目の取得方法(取得できない場合がありますが、推奨されません):
var services = new ServiceCollection();
var provider = services.BuildServiceProvider();

var _valueService = provider.GetService();

2つ目の取得方法(推奨):
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();

    // Do something with service
}

補足:ServiceLocator.Instance.GetService();を使用すると、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();
        }
    }
}
IHttpContextAccessorインターフェースはMicrosoft.AspNetCore.Http.Abstractions Nugetパッケージの下にあります.