[ASP.NET Core]ASP.NET Core应用程序开发中如何手动解决获取依赖注入(DI)的实例?

ASP.NET Core 作者: Rector 14阅读 0评论 0收藏 收藏本文

郑重申明:本文未经许可,禁止任何形式转载

问题描述

在ASP.NET Core的应用程序开发中,依赖注入是不可回避的话题,特别是对于依赖注入的初学者来说。文本讨论如何在运行时通过ASP.NET Core内置的依赖注入框架获取依赖注入的实例。

我们假设在启动配置的依赖注入如下:

Startup.cs:

public void ConfigureServices(IServiceCollection services)
{
    // ...

    services.AddTransient<ISomeService, SomeConcreteService>();
}

在ASP.NET Core应用程序中,Startup.cs启动文件中注入好依赖注入后我们可以通过构造器注入来获取到接口的实例,如:

public class HomeController : Controller
{
    private readonly ISomeService _someService;
    public HomeController(ISomeService someService)
    {
        _someService = someService;
    }

    public IActionResult Get()
    {
        var entity = _someService.FindAll();
        ...
    }
}

上例中的_someService实例是通过构造函数来实现的依赖注入。那么,如何不通过构造函数来手动解决依赖注入而获取到接口的实例呢?类似:

ISomeService service = services.Resolve<ISomeService>();

方案一

在ASP.NET Core的依赖注入框架中,有一个IServiceProvider接口,它提供了一个名为GetService(Type type)的方法,我们可以通过这个方法来获取依赖的实例。

此外,IApplicationBuilderHttpContext类也提供了获取依赖服务的方法,分别为:ApplicationServicesRequestServices属性。

IServiceProvider定义的GetService(Type type)方法解决依赖服务的实例,如下:

var service = (IFooService)serviceProvider.GetService(typeof(IFooService));

我们还可以使用IServiceProvider的静态扩展方法,如下:

serviceProvider.GetService<IFooService>()

扩展方法位于命名空间Microsoft.Extensions.DependencyInjection中。

同时,我们还可以在启动类Startup.cs中使用IServiceProvider来手动解决依赖,如下:

public Startup(IServiceProvider serviceProvider)
{
    var hostingEnv = serviceProvider.GetService<IHostingEnvironment>();
}

或者使用IApplicationBuilder,如下:

public void Configure(IApplicationBuilder app)
{
    var serviceProvider = app.ApplicationServices;
    var hostingEnv = serviceProvider.GetService<IHostingEnvironment>();
}

如果需要在Startup.cs文件中的ConfigureServices()方法中手动解决依赖,还可以:

public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<IFooService, FooService>();

    var sp = services.BuildServiceProvider();
    var fooService = sp.GetService<IFooService>();
}

方案二

使用IServiceProvider接口手动解决依赖实例问题可以有多种方式,如:

Startup.ConfigureServices()方法中

public void ConfigureServices(IServiceCollection services)
{
    services.AddTransient<IMyService, MyService>();

    var serviceProvider = services.BuildServiceProvider();
    var service = serviceProvider.GetService<IMyService>();
}

Startup.Configure()方法中

public void Configure(
    IApplicationBuilder application,
    IServiceProvider serviceProvider)
{
    var service1 = (MyService)serviceProvider.GetService(typeof(MyService));

    var service2 = serviceProvider.GetService<MyService>();

    // ...
}

使用运行时注入

public class Startup
{
    public Startup(
        IHostingEnvironment hostingEnvironment,
        ILoggerFactory loggerFactory)
    {
    }

    public void ConfigureServices(
        IServiceCollection services)
    {
    }

    public void Configure(
        IApplicationBuilder application,
        IHostingEnvironment hostingEnvironment,
        IServiceProvider serviceProvider,
        ILoggerFactory loggerfactory,
        IApplicationLifetime applicationLifetime)
    {
    }
}

通过控制器的Action注入

[HttpGet("/some-action")]
public string SomeAction([FromServices] IMyService myService) => "Hello";

方案三

在控制器中使用IServiceProvider手动解决依赖。

1.首先定义服务接口,ITestService.cs

public interface ITestService
{
    int GenerateRandom();
}

2.实现接口ITestService的类TestService.cs

public class TestService : ITestService
{
    public int GenerateRandom()
    {
        return 888;
    }
}

3.在启动类Startup.cs中注册依赖:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();
    services.AddTransient<ITestService, TestService>();
    // ...
}

4.在控制器中使用IServiceProvider手动解决依赖:

using Microsoft.Extensions.DependencyInjection;

namespace Core.Controllers
{
    public class HomeController : Controller
    {
        public HomeController(IServiceProvider serviceProvider)
        {
            var service = serviceProvider.GetService<ITestService>();
            int rnd = service.GenerateRandom();
        }
    }
}

阅读了该文章的人还浏览了...

本文永久链接码友网 » [ASP.NET Core]ASP.NET Core应用程序开发中如何手动解决获取依赖注入(DI)的实例?

发布于: 2018-11-05 09:02:42
分享扩散: