• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >ASP.NET > 解读ASP.NET 5 & MVC6系列教程(7):依赖注入

解读ASP.NET 5 & MVC6系列教程(7):依赖注入

作者:汤姆大叔 字体:[增加 减小] 来源:互联网 时间:2017-05-11

汤姆大叔通过本文主要向大家介绍了精通asp.net mvc 5,html5 asp.net,pro asp.net mvc 5,asp net mvc 5,asp net培训等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

在前面的章节(Middleware章节)中,我们提到了依赖注入功能(Dependency Injection),ASP.NET 5正式将依赖注入进行了全功能的实现,以便开发人员能够开发更具弹性的组件程序,MVC6也利用了依赖注入的功能重新对Controller和View的服务注入功能进行了重新设计;未来的依赖注入功能还可能提供更多的API,所有如果还没有开始接触依赖注入的话,就得好好学一下了。

在之前版本的依赖注入功能里,依赖注入的入口有MVC中的IControllerFactory和Web API中的IHttpControllerActivator中,在新版ASP.NET5中,依赖注入变成了最底层的基础支撑,MVC、Routing、SignalR、Entity Framrwork等都依赖于依赖注入的IServiceProvider接口,针对该接口微软给出了默认的实现ServiceProvider,以及Ninject和AutoFac版本的包装,当然你也可以使用其它第三方的依赖注入容器,如Castle Windsor等;一旦应用了第三方容器,所有的依赖解析都会被路由到该第三方容器上。

针对通用的依赖类型的解析与创建,微软默认定义了4种类别的生命周期,分别如下:

类型 描述
Instance 任何时间都只能使用特定的实例对象,开发人员需要负责该对象的初始化工作。
Transient 每次都重新创建一个实例。
Singleton 创建一个单例,以后每次调用的时候都返回该单例对象。
Scoped 在当前作用域内,不管调用多少次,都是一个实例,换了作用域就会再次创建实例,类似于特定作用内的单例。

类型注册与示例

依赖注入类型的注册一般是在程序启动的入口中,如Startup.cs中的ConfigureServices中,该类的主要目的就是注册依赖注入的类型。由于依赖注入的主要体现是接口编程,所以本例中,我以接口和实现类的方式来举例。

首先声明一个接口ITodoRepository和实现类TodoRepository1,代码如下:

public interface ITodoRepository
{
 IEnumerable<TodoItem> AllItems { get; }
 void Add(TodoItem item);
 TodoItem GetById(int id);
 bool TryDelete(int id);
}

public class TodoItem
{
 public int Id { get; set; }
 public string Name { get; set; }
}

public class TodoRepository : ITodoRepository
{
 readonly List<TodoItem> _items = new List<TodoItem>();

 public IEnumerable<TodoItem> AllItems
 {
 get { return _items; }
 }

 public TodoItem GetById(int id)
 {
 return _items.FirstOrDefault(x => x.Id == id);
 }

 public void Add(TodoItem item)
 {
 item.Id = 1 + _items.Max(x => (int?)x.Id) ?? 0;
 _items.Add(item);
 }

 public bool TryDelete(int id)
 {
 var item = GetById(id);

 if (item == null) { return false; }

 _items.Remove(item);

 return true;
 }
}
</div>

为了演示不同的声明周期类型,建议多实现几个类,比如TodoRepository2、TodoRepository3、TodoRepository4等,以便进行演示。

然后在ConfigureServices方法内注册接口ITodoRepository类型和对应的实现类,本例中根据不同的生命周期注册了不同的实现类,具体示例如下:

//注册单例模式,整个应用程序周期内ITodoRepository接口的示例都是TodoRepository1的一个单例实例
services.AddSingleton<ITodoRepository, TodoRepository1>();
services.AddSingleton(typeof(ITodoRepository), typeof(TodoRepository1)); // 等价形式

//注册特定实例模型,整个应用程序周期内ITodoRepository接口的示例都是固定初始化好的一个单例实例

TodoRepository2
services.AddInstance<ITodoRepository>(new TodoRepository2());
services.AddInstance(typeof(ITodoRepository), new TodoRepository2()); // 等价形式

//注册作用域型的类型,在特定作用域内ITodoRepository的示例是TodoRepository3
services.AddScoped<ITodoRepository, TodoRepository3>();
services.AddScoped(typeof(ITodoRepository), typeof(TodoRepository3));// 等价形式

//获取该ITodoRepository实例时,每次都要实例化一次TodoRepository4类
services.AddTransient<ITodoRepository, TodoRepository4>();
services.AddTransient(typeof(ITodoRepository), typeof(TodoRepository));// 等价形式

//如果要注入的类没有接口,那你可以直接注入自身类型,比如:
services.AddTransient<LoggingHelper>();
</div>

依赖注入的在MVC中的使用方式目前有三种,分别是Controller的构造函数、属性以及View中的Inject形式。其中构造函数注入和之前的MVC中的是一样的,示例代码如下:

public class TodoController : Controller
{
 private readonly ITodoRepository _repository;

 /// 依赖注入框架会自动找到ITodoRepository实现类的示例,赋值给该构造函数
 public TodoController(ITodoRepository repository)
 {
 _repository = repository;
 }

 [HttpGet]
 public IEnumerable<TodoItem> GetAll()
 {
 return _repository.AllItems; //这里就可以使用该对象了
 }
}
</div>

属性注入,则是通过在属性上加一个[FromServices]属性即可实现自动获取实例。

public class TodoController : Controller
{
 // 依赖注入框架会自动找到ITodoRepository实现类的示例,赋值给该属性
 [FromServices]
 public ITodoRepository Repository { get; set; }

 [HttpGet]
 public IEnumerable<TodoItem> GetAll()
 {
 return Repository.AllItems;
 }
}
</div>

注意:这种方式,目前只适用于Controller以及子类,不适用于普通类
同时:通过这种方式,你可以获取到更多的系统实例对象,如
ActionContext、HttpContext、HttpRequest、HttpResponse、 ViewDataDictionary、以及ActionBindingContext。

在视图中,则可以通过@inject关键字来实现注入类型的实例提取,示例如下:

@using WebApplication1
@inject ITodoRepository repository
<div>
 @repository.AllItems.Count()
</div>
</div>

而最一般的使用方式,则是获取IServiceProvider的实例,获取该IServiceProvider实例的方式目前有如下几种(但范围不同):

var provider1 = this.Request.HttpContext.ApplicationServices; 当前应用程序里注册的Service
var provider2 = Context.RequestServices; // Controller中,当前请求作用域内注册的Service
var provider3 = Resolver; //Controller中
</div>

然后通过GetService和GetRequiredService方法来获取指定类型的实例,示例如下:

var _repository1 = provider1.GetService(typeof(ITodoRepository));
var _repository2 = provider1.GetService<LoggingHelper>();//等价形式
//上述2个对象可能为空

var _repository3 = provider1.GetRequiredService(typeof(ITodoRepository));
var _repository4 = provider1.GetRequiredService<LoggingHelper>();//等价形式
//上述2个对象肯定不为空,因为如果为空的话,会自动抛异常出来
</div>

普通类的依赖注入

在新版的ASP.NET5中,不仅支持上面我们所说的接口类的依赖注入,还支持普通的类型的依赖注入,比如我们生命一个普通类,示例如下:

public class AppSettings
{
 public string SiteTitle { get; set; }
}
</div>

上述普通类要保证有无参数构造函数,那么注册的用法,就应该像如下这样:

services.Configure<AppSettings>(app =>
{
 app.SiteTitle = "111";
});
</div>

使用的时候,则需要获取IOptions<AppSettings>类型的实例,然后其Options属性即是AppSettings的实例,代码如下:

var appSettings = app.ApplicationServices.GetRequiredService<IOptions<AppSettings>>().Options;
<
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • 详解ASP.NET MVC 常用扩展点:过滤器、模型绑定
  • ASP.NET MVC从视图传参到控制器的几种形式
  • ASP.NET MVC 4 中的JSON数据交互的方法
  • ASP.NET MVC制作404跳转实例(非302和200)
  • 详解ASP.NET MVC 利用Razor引擎生成静态页
  • 详解ASP.NET MVC 解析模板生成静态页(RazorEngine)
  • Asp.net MVC下使用Bundle合并、压缩js与css文件详解
  • 详解Asp.Net MVC——控制器与动作(Controller And Action)
  • ASP.NET MVC生成静态页面的方法
  • ASP.NET MVC 导出Word报表

相关文章

  • 2017-05-11利用Timer在ASP.NET中实现计划任务的方法
  • 2018-08-20Asp.Net Core简介与安装教程
  • 2017-05-11asp.net下加密Config的方法
  • 2017-05-11ASP.NET刷新页面的几种方法详解
  • 2017-05-11asp.net(C#)防sql注入组件的实现代码
  • 2017-05-11asp.net Http异常eurl.axd出错信息解决方法
  • 2017-05-11ASP.NET WebAPi(selfhost)实现文件同步或异步上传
  • 2017-05-11ASP.NET、SharePoint中另存文件的长文件名被截断的原因及解决办法
  • 2017-05-11先装了FRAMEWORK,后装IIS导致asp.net页面无法访问的解决方法
  • 2017-05-11Asp.net 时间操作基类(支持短日期,长日期,时间差)

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • 将FreeTextBox做成控件添加到工具箱中的具体操作方法
    • ASP.NET 页面中加添加用户控件的写法
    • Asp.net SignalR应用并实现群聊功能
    • ASP.NET Core简单介绍教程(1)
    • Asp.net中Request.Url的各个属性对应的意义介绍
    • asp.net 数据类型转换类代码
    • ASP.NET MVC中图表控件的使用方法
    • Asp.Net分页和AspNetPager控件的使用
    • asp.net Linq把数据导出到Excel的代码
    • asp.net XMLHttpRequest实现用户注册前的验证

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有