zoukankan      html  css  js  c++  java
  • 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;
            }
    }

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

     

  • 相关阅读:
    2,进程----multiprocessing模块介绍
    1,进程----进程理论知识
    对ORM的理解
    对queryset的理解
    个人总结-10-代码测试整合
    个人总结-9-session的使用,十天免登陆
    个人总结-8-重新写注册和登录界面
    个人总结-7- 实现图片在MySQL数据库中的存储,取出以及显示在jsp页面上
    从人机交互看对搜狗输入法的使用感受
    个人总结6-验证码制作总结
  • 原文地址:https://www.cnblogs.com/afei-24/p/11367425.html
Copyright © 2011-2022 走看看