ASPNET5的依赖注入

ASP.NET5设计的时候就是以DI为基础的,它可以利用内建的框架在Startup类的方法中,把依赖注入进去。应用服务也可以被配置的注入。默认的服务容器提供一些基本的功能,它并不打算代替现代主流的DI框架。

1. 什么是Dependency Injection?

DI的概念相信大家已经了解了,不了解的可以查一下资料。我们来讲一讲ASP.NET 5内建的DI容器。

ASP.NET5包含一个简单的内建容器,它的表现形式是IServiceProvider接口, 默认支持构造函数的注入,ASP.NET通过它注入相关的服务类。ASP.NET的容器引用的类型,在它里面叫做服务,在下面的内容当中,服务就当然于ASP.NET Ioc容器当中管理的类型。你可以通过Startup类中的CongureServices注入内建的服务。

2. 构架提供的服务

Startup类中的ConfigureServices方法定义了应用程序需要的服务,像Entity Framework, MVC等,它由IServiceCollection的扩展方法来添加. 例如:

public void ConfigureServices(IServiceCollection services)

{

  services.AddEntityFramework().AddSqlServer().AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"]));

  services.AddIdentity<ApplicationUser, IdentityRole>().AddEntityFrameworkStores<ApplicationDbContext>().AddDefaultTokenProviders();

      servies.AddMvc();

      services.AddTransient<IEmailSender, AuthMessageSender>();

  services.AddTransient<ISmsSender, AuthMessageSender>();

}

3. 注册你自己的服务

上面的代码当中:

services.AddTransient<IEmailSender, AuthMessageSender>();

services.AddTransient<ISmsSender, AuthMessageSender>();

AddTransient方法用来添加抽象类型到具体的类型映射,并且申明了它的生命周期,在你注册服务时,选择合适的对象生命周期很重要。

我们来看一个例子:

public class CharactersController : Controller

{

  private readonly ICharacterRepository _characterRepository;

  public CharactersController(ICharacterRepository characterRepository)

  {

    _characterRepository = characterRepository;

  }

  public IActionResult Index()

  {

    var characters = _characterRepository.ListAll();

    return View(characters);

  }

}

public interface ICharacterRepository

{

   IEnumberable<Character> ListAll();

}

public class CharacterRepository : ICharacterRepository

{

  private readonly ApplicationDbContext _dbContext;

  public CharacterRepository(ApplicationDbContext dbContext)

  {

    _dbContext = dbContext;

  }

  public IEnumerable<Character> ListAll()

  {

    return _dbContext.Characters.AsEnumberable();

  }

}

注意CharacterRepository的构造函数当中需要一个ApplicationDbContext,像它这样的注入方式并不常见,在每个申请当中,容器负责提供每一个对象的具体依赖对象。

在这个例子当中,ICharacterRepository和ApplicationDbContext都必须在ConfigureServices当中被注册。

services.AddEntityFramework().AddSqlServer().AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(Configuration["Data:DefaultCOnnection:ConnectionString"]));

services.AddScoped<ICharacterRepository, CharacterRepository>();

EntityFramework context 应该被以Scoped的生命周期增加到容器当中,Repositories用到EntityFramework, 所以它应该使用同一个生命周期。

4. 服务的生命周期和注册选项

ASP.NET 服务可以配置对象的生命周期如下所示:

Transient

  它是意思每个请求都创建一个新的对象,这个适合轻量的,无状态的服务。

Scoped

  每个申请只创建一个对象。

Singleton

  它是在首次被申请调用时创建一次, 以后所有的请求都会被重用,如果你的应用程序需要单例,推荐使用些方法,而不要自己实现单例模式。

Instance

  它与Singleton相似 ,唯一的区别是,Instance在ConfigureServices的时候就创建了,而Singleton要在第一次请求的时候才创建。

5. 请求的服务和应用服务

ASP.NET当中服务在HttpContext的ApplicationServices和RequestServices中能够得到

RequestServices里的服务是配置和请求你的应用程序的一部分,ApplicationServices里的服务是被限制在应用程序启动的时候的服务,任何Scoped的应用程序都能在RequestServices得到,但是在ApplicationServices里得不到。当你的对象申明依赖时,这些依赖在RequestServices里能够得到,在ApplicationServices里得不到,

一般地,你不需要直接用这些属性,而可以通过构造函数注入。

6. 用DI设计你的服务

你应该用DI来设计你的应用,不要用函数状态的静态方法调用,或者直接地实例化你的服务。用DI ,你的类比较小,而且是灵活的,可测试的。

当你一个类依赖很多的时候,你就要意识到是否违反了单一职责原则。你可以重构你的代码,把一些依赖移到其它的新类当中。注意在你Controler 类当中应该注意在UI上面,因此你的业务逻辑和数据访问通过UI的职责的分来被相应地合理分开。

当用到数据访问时,你可以注入EntityFramework的DbContext类型到你的controllers里面,不过首先你要确保EF在Startup类中被配置了,然而,避免在UI里直接使用DbContext, 你应该把它放到抽象当中去,例如Repository的接口中去。这样可以减少你的应用和数据的耦合。也能使你的应用程序可以很容易地被测试。

7 替代默认的服务容器

在ASP.NET当中,你可以很容易地替代内建的服务容器,在ConfigureServices方法当中一般返回void, 但是如果它返回IServiceProvider, 一个不同的容器可以被返回,我们以autofac为例。

首选,你必须在project.json加如下的配置:

"dependencies":{

  "Autofac": "4.0.0-beta8",

  "Autofac.Framework.DependencyInjection": "4.0.0-beta8"

},

接下来,改写ConfigureServices

public IServiceProvider ConfigureServices(IServiceCollection services)

{

  services.AddMvc();

  

  // Add Autofac

  var containerBuilder = new ContainerBuilder();

  containerBuilder.RegisterModule<DefaultModule>();

  containerBuilder.Populate(services);

  var container = containerBuilder.Build();

  return container.Resolve<IServiceProvider>();

}

最后,配置Autofac在DefaultModule里面

public class DefaultModule : Module

{

  protected override void Load(ContainerBuilder builder)

  {

    builder.RegisterType<CharacterRepository>.As<ICharacterRepository>();

  }

}

现在,Autoface被用来生成你的服务在DI里面。

ASP.NET 5/DNX Containers

Autofac.Dnx     http://autofac.org

StructureMap.Dnx   http://structuremap.github.io

8. 建议

* DI用于复杂的依赖,控制器、服务、仓储等

* 不要直接利用DI存储数据和配置

* 不要静态地访问服务

* 不要在应用程序当中手动使用服务定位

* 不要静态地访问HttpContext

记住,不要把DI和static/global对应混用,否则你就感觉不到DI的好处了

转载于:https://www.cnblogs.com/superkklot/p/5055685.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/397033.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java 权限控制 demo_Java-访问控制权限

Java面向对象-访问控制权限Java中&#xff0c;可以通过一些Java关键字&#xff0c;来设置访问控制权限&#xff1b;主要有 private(私有)&#xff0c; package(包访问权限)&#xff0c;protected(子类访问权限)&#xff0c;public(公共访问权限)privatepackageprotectedpublic同…

《未来世界的幸存者》笔记

https://ruanyf.github.io/survivor/ 这两天一直在上下班途中&#xff0c;读阮一峰的这本书 《未来世界的幸存者》。还是有不少感慨的。做一下记录。 未来人类社会的形态&#xff0c;将发生颠覆性的变化。旧的社会结构已经在崩溃了&#xff0c;但社会底层的机会变得更少了&…

python类中没有属性_如何在python语言中在类中删除属性和添加属性

在python语言中的类&#xff0c;可以使用class定义类&#xff0c;调用__init__方法进行初始化&#xff1b;默认传入self&#xff0c;可以在后面在添加几个属性。可以使用setattr()添加属性&#xff0c;也可以使用delattr()删除属性。下面利用几个实例说明这两个方法的用法&…

mysql 数据复制停止工作_linux – Mysql GTID复制停止工作

我在主服务器和从服务器之间设置了mysql gtid复制.有趣的是,我发现复制在几分钟后停止工作,我必须使用stop slave并启动slave来重启mysql复制.谁能告诉我是什么原因导致这个问题&#xff1f;改变奴隶主&#xff1a;mysql> change master to-> master_host master.com,-&…

python学生管理系统gui版好例子网_python图书管理系统gui 相关实例(示例源码)下载 - 好例子网...

开发语言&#xff1a;Python | 大小&#xff1a;19.05M | 发布时间&#xff1a;2019-05-27 | 发布人&#xff1a;李易峰 相关标签&#xff1a; 立即下载 开发语言&#xff1a;Python | 大小&#xff1a;0.21M | 发布时间&#xff1a;2020-08-23 | 发布人&#xff1a;聂嘉辉 相关…

COM组件的运行机制

COM组件的运行机制  构造一个创建COM组件的最小框架结构    IUnknown *pUnkNULL;    IObject *pObjectNULL;    CoInitialize(NULL);    CoCreateInstance(CLSID_Object, CLSCTX_INPROC_SERVER, NULL, IID_IUnknown, (void**)&pUnk);    pUnk->Qu…

申请去国外读博士

必须要做的事情是&#xff1a; 考过GRE和TOEFL 准备推荐信 个人CV 联系导师一般就是发邮件 转载于:https://www.cnblogs.com/zhulinmails/p/5078695.html

动态编译

下面的demo就涵盖了动态编译和运行类的过程 package 动态编译; import java.lang.reflect.Method;import java.net.URL;import java.net.URLClassLoader; import javax.tools.JavaCompiler;import javax.tools.ToolProvider; public class Demo { public static void main(Stri…

python怎么打开spyder_Python开发环境Spyder安装方法

Spyder(Scientific PYthon Development EnviRonment)是一个强大的交互式 Python 语言开发环境&#xff0c;提供高级的代码编辑、交互测试、调试等特性&#xff0c;支持包括 Windows、Linux 和 OS X 系统。 本文在只安装过python2.7的Win7环境下进行安装Spyder&#xff0c;其他环…

矩阵、向量求导法则

复杂矩阵问题求导方法&#xff1a;可以从小到大&#xff0c;从scalar到vector再到matrix。 x is a column vector, A is a matrix practice: 转载于:https://www.cnblogs.com/vincentQin/p/5406010.html

java字符函数_java字符串函数用法汇总

替换字符串中的字符例如有如下x的字符串String x "[kllkklk\kk\kllkk]";要将里面的“kk”替换为&#xff0c;可以使用两种方法得到相同的结果replace(CharSequence target, CharSequence replacement) —— x.replace("kk", "")replaceAll(Stri…

[Vue]Scoped Css与Css Modules的区别

均为解决CSS全局作用域问题&#xff08;样式冲突&#xff08;污染&#xff09;&#xff09;的一个解决方案。 1.Scoped CSS 当 <style> 标签有 scoped 属性时&#xff0c;相当于在元素中添加了一个唯一属性用来区分。 <style scoped> .example {color: red; } <…

mysql数据库-mysql数据定义语言DDL (Data Definition Language)归类(六)

0x01 创建数据库并指定字符集和排序规则 -- 三种实例写法 create database temptab2 character set utf8 collate utf8_general_ci; create database temptab3 charset utf8 collate utf8_general_ci; create database temptab4 character setutf8 collate utf8_general_ci; 查…

vue antd admin怎么切换到basic分支_vue菜鸟从业记:前端如何与后端哥们进行接口联调...

最近我的朋友王小闰进入一家新的公司&#xff0c;正好公司项目采用的是前后端分离架构&#xff0c;技术栈是王小闰非常熟悉的vue全家桶&#xff0c;后端用的是Java语言。在前后端开发人员碰面之后&#xff0c;协商确定好了前端需要的数据接口(扯那么多&#xff0c;其实也就是关…

ASP.NET AntiXSS的作用

XSS跨站脚本攻击是指用户输入HTML编码对网站进行跨站攻击。通过使用FCKeditor、FreeTextBox、Rich TextBox、Cute Editor、TinyMCE等等Html编辑器&#xff0c;用户可以输入一些危险字符&#xff0c;注入到网站中&#xff0c;形式XSS。&#xff08;一般的解决办法是使用BBCode的…

p1358

这是一道二维树状数组模板题。 需要注意的可能只有这些xy有可能为零。那每次输入之后全部&#xff0c;相当于全部向右下角移了一位。 那就直接给代码了呦。 using namespace std; int c[1050][1050],n,m; int i,f; int a1,b1,a2,b2,tx,ty,tk; int ans; int lowbit(int x) {retu…

java中对象的生存期_深入理解Java虚拟机-判断对象是否存活算法与对象引用

我们知道Java中的对象一般存放在堆中&#xff0c;但是总不能让这些对象一直占着内存空间&#xff0c;这些对象最终都会被回收并释放内存&#xff0c;那么我们如何判断对象已经成为垃圾呢&#xff1f;这篇文章会提出两种算法解决这个问题。另外&#xff0c;本文还要谈一谈对象引…

大数据高效复制的处理案例分析总结

一个老客户提出这样的需求&#xff0c;希望将SQLServer中的某个表的数据快速复制到SQLite数据库里面以便进行定期的备份处理&#xff0c;数据表的记录大概有50多万条记录&#xff0c;表有100个字段左右&#xff0c;除了希望能够快速做好外&#xff0c;效率是第一位的&#xff0…

@autowired注解注入为null_Intellij IDEA中Mybatis Mapper自动注入警告的6种解决方案

相信使用Mybaits的小伙伴们一定会经常编写类似如下的代码&#xff1a;可以看到 userMapper 下有个红色警告。虽然代码本身并没有问题&#xff0c;能正常运行&#xff0c;但有个警告总归有点恶心。本文分析原因&#xff0c;并列出解决该警告的几种方案。原因众所周知&#xff0c…

五 Python之socket网络编程

<1>socket概念 socket通常也称作"套接字"&#xff0c;用于描述IP地址和端口&#xff0c;是一个通信链的句柄&#xff0c;应用程序通常通过"套接字"向网络发出请求或者应答网络请求。ocket本质上就是在2台网络互通的电脑之间&#xff0c;架设一个通道…