700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > ASP.NET Core MVC 之依赖注入 Controller

ASP.NET Core MVC 之依赖注入 Controller

时间:2020-02-01 19:37:00

相关推荐

ASP.NET Core MVC 之依赖注入 Controller

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

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

1.构造函数注入

Core 内置的基于构造函数的依赖注入支持扩展到 MVC 控制器。通过只添加一个服务类型作为构造函数参数到控制器中, 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: DateTimepublic ActionResult Index(){var serverTime = _dateTime.Now;if (serverTime.Hour < 12){ViewData["Message"] = "Good Morning";}return View();}}

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;}}

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

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。