ASP.NET Core MVC 之依赖注入 Controller

Posted afei-24

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ASP.NET Core MVC 之依赖注入 Controller相关的知识,希望对你有一定的参考价值。

  ASP.NET Core MVC 控制器应通过构造函数明确地请求它们地依赖关系,在某些情况下,单个控制器地操作可能需要一个服务,在控制器级别上的请求可能没有意义。在这种情况下,也可以将服务作为  Action 的参数。

  依赖注入是一种如 Dependency Inversion Principle 所示的技术,允许应用程序松散耦合的模块组成。

1.构造函数注入

  ASP.NET Core 内置的基于构造函数的依赖注入支持扩展到 MVC 控制器。通过只添加一个服务类型作为构造函数参数到控制器中,ASP.NET Core 将会尝试使用内置服务容器解析这个类型。服务通常(但不总是)使用接口定义。例如,如果应用程序定义一个检索时间的服务,然后依赖注入而不是硬编码:

  定义接口和实现:

namespace MVCTest.Services

    public interface IDateTime
    
        DateTime Now  get; 
    
    public class SystemDateTime: IDateTime
    
        public DateTime Now
        
            get  return DateTime.Now; 
        
    

  在 ConfigureServices 中注册服务到容器:

services.AddTransient<IDateTime, SystemDateTime>();

  在控制其中使用:

    public class DateTimeController : Controller
    
        private IDateTime _dateTime;
        public DateTimeController(IDateTime dateTime)
        
            _dateTime = dateTime;
        
        // GET: DateTime
        public ActionResult Index()
        
            var serverTime = _dateTime.Now;
            if (serverTime.Hour < 12)
            
                ViewData["Message"] = "Good Morning";
            
            return View();
        

  ASP.NET Core 内置的依赖注入支持用于请求服务的类型只能有一个构造函数,如果多于一个会报异常。使用第三方实现替换默认依赖注入,可以实现支持多个构造函数。

 

2.使用 FromServices 操作注入

  有时,不需要在控制器为多个操作提供服务。在这种情况下,将服务注入到操作方法的参数是有意义的。通过 [FromServices] 标记参数来实现:

        public ActionResult Index([FromServices] IDateTime _dateTime)
        
            var serverTime = _dateTime.Now;
            if (serverTime.Hour < 12)
            
                ViewData["Message"] = "Good Morning";
            
            return View();
        

 

3.在控制器中访问设置

  在控制器中访问应用程序设置或者配置设置时常见的模式。此访问应当使用在 Configuration 中描述的访问模式。通常不应从控制器中使用依赖注入直接请求设置,更好的方式是请求 IOptions<T> 实例,T是你需要的配置类型。例如:

  创建选项类:

public class AppSettingOptions
    
        public DefaultConnec ConnectionStrings  get; set; 
        public string AllowedHosts  get; set; 
    

    public class DefaultConnec
    
        public string DefaultConnection  get; set; 
    

appsettings.json:


  "ConnectionStrings": 
    "DefaultConnection": "Data Source=.;Initial Catalog=Test;Integrated Security=True"
  ,
  "Logging": 
    "LogLevel": 
      "Default": "Information"
    
  ,
  "AllowedHosts": "*"

  配置应用程序使用选项模型,在 ConfigureServices 中添加配置类到服务容器:

public Startup(IConfiguration configuration,IHostingEnvironment env)
        
            //Configuration = configuration;
            var builder = new ConfigurationBuilder()
                .SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("appsettings.json",optional:true,reloadOnChange:true)
                //.AddJsonFile($"appsettings.env.EnvironmentName.json",optional:true)
                ;

            //配置环境变量
            //builder.AddEnvironmentVariables();
            Configuration = builder.Build();
        

        public IConfiguration Configuration  get; 

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        
            services.AddOptions();
            services.Configure<AppSettingOptions>(Configuration);
            //通过代码编写
            services.Configure<AppSettingOptions>(options=>
            
                options.AllowedHosts = "test";
            );
        

  示例是从 appsettings.json 读取设置,也可以在代码中添加设置。

  一旦指定了请类型的配置对象 AppSettingOptions,并将其添加到服务容器,就可以在控制器或操作方法通过请求 IOptions<AppSettingOptions>  的实例获取它:

    public class HomeController : Controller
    
        private readonly IOptions<AppSettingOptions> _options;
        public HomeController(IOptions<AppSettingOptions> options)
        
            _options = options;
        

  遵循选项模式允许将设置和配置彼此分离,并且确保控制器遵循关注点分离,因为不需要知道如何在哪里找到设置信息。由于控制器类中没有静态附着或者直接实例化设置类,因此使得控制器更容易使用单元测试。

 

 

 

 

以上是关于ASP.NET Core MVC 之依赖注入 Controller的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET Core Web 应用程序系列- 在ASP.NET Core中使用Autofac替换自带DI进行构造函数和属性的批量依赖注入(MVC当中应用)

ASP.NET Core Web 应用程序系列- 在ASP.NET Core中使用Autofac替换自带DI进行批量依赖注入(MVC当中应用)

ASP.Net Core MVC 依赖注入不起作用

ASP.NET Core Web 应用程序系列- 使用ASP.NET Core内置的IoC容器DI进行批量依赖注入(MVC当中应用)

如何在 ASP.NET Core MVC 中使用依赖注入设计存储库模式?

asp.net core 系列之Dependency injection(依赖注入)