web-dev-qa-db-ja.com

ASP.NET Core DependencyResolver

ASP.NET MVC 5では、DependencyResolver.Current.GetService<T>()を介して依存関係を取得できます。 ASP.NET Coreに同様のものはありますか?

14
analyser

はいあります。 ASP.NET Core 1.0.0では、HttpContextからのリクエスト内で利用可能なサービスは、RequestServicesコレクションを通じて公開されます。[1]

this.HttpContext.RequestServices

GetServiceメソッドを使用して、依存関係のタイプを指定することにより、依存関係を取得できます。

this.HttpContext.RequestServices.GetService(typeof(ISomeService));

一般に、これらのプロパティを直接使用しないでください。代わりに、クラスのコンストラクタを介して必要なクラスのタイプをリクエストし、フレームワークにこれらの依存関係を挿入させます。これにより、テストが容易になり、疎結合のクラスが生成されます。

[1] https://docs.asp.net/en/latest/fundamentals/dependency-injection.html#request-services

17
Sergio Vicente

本当に必要な場合は、独自に作成できます。まず、AppDependencyResolverクラスを作成します。

_public class AppDependencyResolver
{
    private static AppDependencyResolver _resolver;

    public static AppDependencyResolver Current
    {
        get
        {
            if (_resolver == null)
                throw new Exception("AppDependencyResolver not initialized. You should initialize it in Startup class");
            return _resolver;
        }
    }

    public static void Init(IServiceProvider services)
    {
        _resolver = new AppDependencyResolver(services);
    }

    private readonly IServiceProvider _serviceProvider;

    public object GetService(Type serviceType)
    {
        return _serviceProvider.GetService(serviceType);
    }

    public T GetService<T>()
    {
        return _serviceProvider.GetService<T>();
    }

    private AppDependencyResolver(IServiceProvider serviceProvider)
    {
        _serviceProvider = serviceProvider;
    }
} 
_

_serviceProvider.GetService<T>();は、_using Microsoft.Extensions.DependencyInjection;_を追加した場合にのみ使用できることに注意してください。 _"Microsoft.Extensions.DependencyInjection": "1.0.0"_に_project.json_を追加すると、その名前空間が使用可能になります。 Initクラスでstartupメソッドを呼び出す必要があります。例えば

_    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        AppDependencyResolver.Init(app.ApplicationServices);
        //all other code
_

その後は、_DependencyResolver.Current_と同じように、どこでも使用できます。しかし、私の提案-他に選択肢が残っていない場合にのみ使用してください。

9
YuriyP

.Net core 2.0で私のために働いた方法はここにあります

public ViewResult IndexWithServiceLocatorPattern([FromServices]ProductTotalizer totalizer)
{
    var repository = (IRepository)HttpContext.RequestServices.GetService(typeof(IRepository));
    ViewBag.HomeController = repository.ToString();
    ViewBag.Totalizer = totalizer.repository.ToString();
    return View("Index", repository.Products);
}

クラシカルなやり方でやらなければならないとしたら、以下のようになります。

public class HomeController : Controller
{
    private readonly IRepository repo;

    /// <summary>
    /// MVC receives an incoming request to an action method on the Home controller. 
    /// MVC asks the ASP.NET service provider component for a new instance of the HomeController class.
    /// The service provider inspects the HomeController constructor and discovers that it has a dependency on the IRepository interface. 
    /// The service provider consults its mappings to find the implementation class it has been told to use for dependencies on the IRepository interface. 
    /// The service provider creates a new instance of the implementation class. 
    /// The service provider creates a new HomeController object, using the implementation object as a constructor argument.
    /// The service provider returns the newly created HomeController object to MVC, which uses it to handle the incoming HTTP request.
    /// </summary>
    /// <param name="repo"></param>
    public HomeController(IRepository repo)
    {
        this.repo = repo;
    }

    /// <summary>
    ///  Using Action Injection
    ///  MVC uses the service provider to get an instance of the ProductTotalizer class and provides it as an
    ///  argument when the Index action method is invoked.Using action injection is less common than standard
    ///  constructor injection, but it can be useful when you have a dependency on an object that is expensive to
    ///  create and that is required in only one of the action methods defined by a controller
    /// </summary>
    /// <param name="totalizer"></param>
    /// <returns></returns>
    public ViewResult Index([FromServices]ProductTotalizer totalizer)
    {
        ViewBag.Total = totalizer.repository.ToString();
        ViewBag.HomeCotroller = repo.ToString();
        return View(repo.Products);
    }
}
7
Bharat

Asp.netコアで利用可能なサービス、そのHttpContext

this.HttpContext.RequestServices

このサービスを利用することで、サービスを受けることができます。また、GetServiceメソッドを使用して、依存関係のタイプを指定することにより、依存関係を取得できます。

this.HttpContext.RequestServices.GetService(typeof(ISomeService));
4
Jani Devang

IServiceProviderには、GetService、GetRequiredService、GetServicesの拡張メソッドがあります。すべてにジェネリックバージョンと非ジェネリックバージョンがあります。 Asp.Net Core Webプロジェクトでは、DIを介して、またはIApplicationBuilderからIServiceProviderへの参照を取得できます。コンソールアプリでは、IServiceProviderの独自のインスタンスを作成し、どこかに参照を保存する必要があります

var services = new ServiceCollection();
...
ServiceProvider = services.BuildServiceProvider();
2
Vitaly

これは良いスタートになると思います:

これは、asp.net 5の依存関係注入の公式ドキュメントです。

依存関係注入がasp.net 5に組み込まれましたが、autofacなどの他のライブラリを自由に使用できます。デフォルトのものは私にとってはうまくいきます。

あなたのスターアップクラスには、このようなメソッドがあります

public void ConfigureServices(IServiceCollection services)
{

    //IServiceCollection acts like a container and you 
    //can register your classes like this:

    services.AddTransient<IEmailSender, AuthMessageSender>();
    services.Singleton<ISmsSender, AuthMessageSender>();
    services.AddScoped<ICharacterRepository, CharacterRepository>();

}

から:

DependencyResolver Asp.net 5.

0
Destrif