第四节:配置的读取、StartUp类、内置依赖注入和扩展改造
一. 配置的读取
在Asp.Net Core中,有一个 appsettings.json 文件,用于存储相应的配置信息,读取的时,要通过构造函数注入:IConfiguration Configuration,来进行读取。
下面是一段配置文件,我们来对其进行读取:
读取代码:
public IConfiguration Configuration { get; }
public FirstController(IConfiguration configuration)
{
Configuration = configuration;
}
{
var f0 = Configuration["MyFullName"];
var f1 = Configuration["User:userName"];
var f2 = Configuration["User:Child:childName"];
var f3 = Configuration["StudentList:0:sName"];
var f4 = Configuration["StudentList:1:sName"];
}
二. StartUp类
1. 说明:
StartUp类中包括两个方法,分别是ConfigureServices和Configure,前者主要用来注册服务,后者主要用来创建和配置请 求管道,然后在Main方法中进行调用:
WebHost.CreateDefaultBuilder(args).UseStartup<Startup>();
2. ConfigureServices方法
(1). 它在Configure方法调用之前,由主机调用。
(2). 需要大量设置的功能,IServiceCollection 上有 Add{Service} 扩展方法,常见的如下:
a:services.AddDbContext<ApplicationDbContext>(options =>options.UseSqlServer( Configuration.GetConnectionString("DefaultConnection")));
b:services.AddDefaultIdentity<IdentityUser>().AddDefaultUI(UIFramework.Bootstrap4).AddEntityFrameworkStores<ApplicationDbContext>();
c:services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
3. Configure方法
(1).用于配置Http请求管道,主要通过IApplicationBuilder实例来配置。
(2).常见的管道有:
开发人员异常页(UseDeveloperExceptionPage)、
HTTP严格传输安全性(UseHsts)、
HTTPS重定向(UseHttpsRedirection)、
静态文件(UseStaticFiles)、
MVC(UseMvc)。
三. 内置依赖注入和扩展改造
1. 说明:
这里不再介绍什么是IOC和DI,直接介绍内置依赖注入的使用方法和生命周期,最后介绍利用AutoFac进行替换内置IOC容器。事先准备好U1-U4四个类和IU1-IU4四个接口。
接口和类的代码:
public interface IU1
{
string guid { get; set; }
string GetName();
}
public interface IU2
{
string guid { get; set; }
string GetName();
}
public interface IU3
{
string guid { get; set; }
string GetName();
}
public interface IU4
{
string guid { get; set; }
string GetName();
}
接口
public class U1 : IU1
{
public string guid { get; set; } public U1()
{
guid = System.Guid.NewGuid().ToString("N");
} /// <summary>
/// 调用方法的时候,是单例也没有用,每次调用都会变
/// </summary>
/// <returns></returns>
public string GetName()
{
return System.Guid.NewGuid().ToString("N");
}
}
public class U2 : IU2
{
public string guid { get; set; } public U2()
{
guid = System.Guid.NewGuid().ToString("N");
} /// <summary>
/// 调用方法的时候,是单例也没有用,每次调用都会变
/// </summary>
/// <returns></returns>
public string GetName()
{
return System.Guid.NewGuid().ToString("N");
}
}
public class U3 : IU3
{
public string guid { get; set; } public U3()
{
guid = System.Guid.NewGuid().ToString("N");
} /// <summary>
/// 调用方法的时候,是单例也没有用,每次调用都会变
/// </summary>
/// <returns></returns>
public string GetName()
{
return System.Guid.NewGuid().ToString("N");
}
}
public class U4 : IU4
{
public string guid { get; set; } public U4()
{
guid = System.Guid.NewGuid().ToString("N");
} /// <summary>
/// 调用方法的时候,是单例也没有用,每次调用都会变
/// </summary>
/// <returns></returns>
public string GetName()
{
return System.Guid.NewGuid().ToString("N");
}
}
类
2. 核心:
利用IServiceCollection services这个对象进行注册,而这个对象在Startup类中的ConfigureServices中已经注入进去了, 也就是说我在自定义对象的注册是的时候,可以直接在ConfigureServices类中进行注册,然后在控制器中使用的时候通过构造函数进行注入即可。
PS:我们也可以自己 IServiceCollection container = new ServiceCollection(); 然后进行注册(不推荐,特殊情况下可能这么用)
3. 生命周期分为三种:
瞬时的(AddTransient)、请求内单例(AddScoped)、单例(AddSingleton 两种写法)。
4. 测试:
两次访问该页面,发现ViewBag.r1 和 ViewBag.r2两次的值不同,ViewBag.r3和ViewBag.r4两次的值相同。
代码分享:
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); //自定义注册对象
{
services.AddTransient<IU1, U1>(); //瞬时的
services.AddScoped<IU2, U2>(); //一次请求内是不变的
services.AddSingleton<IU3, U3>(); //单例的
services.AddSingleton<IU4>(new U4()); //单例的 }
}
public class FirstController : Controller
{
public IU1 U1 { get; }
public IU1 U11 { get; }
public IU2 U2 { get; }
public IU2 U22 { get; }
public IU3 U3 { get; }
public IU3 U33 { get; }
public IU4 U4 { get; }
public IU4 U44 { get; } public FirstController(IU1 u1, IU1 u11, IU2 u2, IU2 u22, IU3 u3, IU3 u33, IU4 u4, IU4 u44)
{
U1 = u1;
U11 = u11;
U2 = u2;
U22 = u22;
U3 = u3;
U33 = u33;
U4 = u4;
U44 = u44;
} public IActionResult Index()
{
bool a = object.ReferenceEquals(U1, U11);
bool b = object.ReferenceEquals(U2, U22);
bool c = object.ReferenceEquals(U3, U33);
bool d = object.ReferenceEquals(U4, U44); //分两次请求来查看
ViewBag.r1 = U1.guid;
ViewBag.r2 = U2.guid;
ViewBag.r3 = U3.guid;
ViewBag.r4 = U4.guid; //下面是自己创建的的模式进行访问
{
IServiceCollection container = new ServiceCollection();
container.AddTransient<IU2, U2>();
//要放在注册的后面
var provider = container.BuildServiceProvider();
IU2 user1 = provider.GetService<IU2>();
IU2 user2 = provider.GetService<IU2>();
bool cc = object.ReferenceEquals(user1, user2); }
return View();
}
}
<div class="text-center">
<h1 class="display-4">Welcome</h1>
<p>瞬时的:@ViewBag.r1</p>
<p>请求内单例:@ViewBag.r2</p>
<p>全局单例写法1:@ViewBag.r3</p>
<p>全局单例写法2:@ViewBag.r4</p>
</div>
补充:
如果不想通过构造函数注入,则可以通过[FromServices]特性来给某个特定方法注入:
如: public void Test(【FromServices】IU1 u1){ }。
两次访问的请求结果
5. 为什么要用AutoFac进行替换内置容器?
因为某些特定的功能内置的容器不支持,比如:属性的注入、基于名称的注入、子容器、自定生存期管理、对迟缓初始化的 Func<T> 支持
6. 用AutoFac替换的步骤
(1). 通过Nuget安装AutoFac【4.9.2】和Autofac.Extensions.DependencyInjection【4.4.0】
(2). 改造ConfigureServices中配置容器并返回IServiceProvider,配置代码详见具体类,注入的代码封装到DefaultModule。
public IServiceProvider ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); // Add Autofac
var containerBuilder = new ContainerBuilder();
containerBuilder.RegisterModule<DefaultModule>();
containerBuilder.Populate(services);
var container = containerBuilder.Build();
return new AutofacServiceProvider(container);
}
DefaultModule代码分享
特别注意:AutoFac的生命周期也有:瞬时的、单次请求内单例的、全局单例的。
public class DefaultModule: Module
{
protected override void Load(ContainerBuilder builder)
{
//这里就是AutoFac的注入方式,下面采用常规的方式
//详见:https://www.cnblogs.com/yaopengfei/p/9479268.html
//官网:https://autofac.org/ //特别注意:其中很大的一个变化在于,Autofac 原来的一个生命周期InstancePerRequest,将不再有效。正如我们前面所说的,整个request的生命周期被ASP.NET Core管理了,
//所以Autofac的这个将不再有效。我们可以使用 InstancePerLifetimeScope ,同样是有用的,对应了我们ASP.NET Core DI 里面的Scoped。 //瞬时请求(省略InstancePerDependency 也为瞬时)
builder.RegisterType<U1>().As<IU1>().InstancePerDependency();
//单次请求内单例
builder.RegisterType<U2>().As<IU2>().InstancePerLifetimeScope();
//全局单例
builder.RegisterType<U3>().As<IU3>().SingleInstance();
builder.RegisterType<U4>().As<IU4>().SingleInstance(); }
}
(3). 其他都不变,可以继续沿用构造函数注入。
参考文章:
https://www.cnblogs.com/yaopengfei/p/9479268.html (.Net 平台下的AutoFac的用法)
https://www.cnblogs.com/jesse2013/p/di-in-aspnetcore.html
!
- 作 者 : Yaopengfei(姚鹏飞)
- 博客地址 : http://www.cnblogs.com/yaopengfei/
- 声 明1 : 本人才疏学浅,用郭德纲的话说“我是一个小学生”,如有错误,欢迎讨论,请勿谩骂^_^。
- 声 明2 : 原创博客请在转载时保留原文链接或在文章开头加上本人博客地址,否则保留追究法律责任的权利。
第四节:配置的读取、StartUp类、内置依赖注入和扩展改造的更多相关文章
- 多态,封装,反射,类内置attr属性,os操作复习
1.多态 #多态 多态是指对象如何通过他们共同的属性和动作来操作及访问,而不需要考虑他们具体的类 运行时候,多种实现 反应运行时候状态 class H2O: def __init__(self,nam ...
- 使用react全家桶制作博客后台管理系统 网站PWA升级 移动端常见问题处理 循序渐进学.Net Core Web Api开发系列【4】:前端访问WebApi [Abp 源码分析]四、模块配置 [Abp 源码分析]三、依赖注入
使用react全家桶制作博客后台管理系统 前面的话 笔者在做一个完整的博客上线项目,包括前台.后台.后端接口和服务器配置.本文将详细介绍使用react全家桶制作的博客后台管理系统 概述 该项目是基 ...
- 开涛spring3(12.2) - 零配置 之 12.2 注解实现Bean依赖注入
12.2 注解实现Bean依赖注入 12.2.1 概述 注解实现Bean配置主要用来进行如依赖注入.生命周期回调方法定义等,不能消除XML文件中的Bean元数据定义,且基于XML配置中的依赖注入的 ...
- [转]后台页面访问权限:页面基类&内置票据认证 使用方法
本文转自:http://www.cnblogs.com/fishtreeyu/archive/2011/01/29/1947421.html 一般网站后台页面除了登录页面login.aspx未登录用户 ...
- spring接口多实现类,该依赖注入哪一个?
一.问题的描述 在实际的系统应用开发中我经常会遇到这样的一类需求,相信大家在工作中也会经常遇到: 同一个系统在多个省份部署. 一个业务在北京是一种实现方式,是基于北京用户的需求. 同样的业务在上海是另 ...
- SpringBoot系列三:SpringBoot基本概念(统一父 pom 管理、SpringBoot 代码测试、启动注解分析、配置访问路径、使用内置对象、项目打包发布)
声明:本文来源于MLDN培训视频的课堂笔记,写在这里只是为了方便查阅. 1.了解SpringBoot的基本概念 2.具体内容 在之前所建立的 SpringBoot 项目只是根据官方文档实现的一个基础程 ...
- Python之路【第四篇】: 函数、递归、内置函数
一. 背景提要 现在老板让你写一个监控程序,监控服务器的系统状况,当cpu\memory\disk等指标的使用量超过阀值时即发邮件报警,你掏空了所有的知识量,写出了以下代码 while True: i ...
- 利用.net Core 对程序集中的类 进行统一依赖注入
1.创建特性 用于标注依赖注入 using Microsoft.Extensions.DependencyInjection; using System; using System.Collectio ...
- 第四章 函数之lambda 表达式和内置函数
4.5 lambda 表达式 用于表示简单的函数. # 三元运算,为了解决简单的if else的情况,如:if 1 == 1: a = 123else: a = 456# 相当于a = 1 ...
随机推荐
- linux sed、awk、grep同时匹配多个条(并且 or 或者)
同时匹配ABC 和 abc: sed -n '/ABC/{/abc/p}' awk '/ABC/&&/abc/{ print $0 }' grep -E '(ABC.*abc|abc. ...
- 隐马尔科夫模型(Hidden Markov Models) 系列之四
转自:http://blog.csdn.net/eaglex/article/details/6430389 前向算法(Forward Algorithm) 一.如果计算一个可观察序列的概率? 1 ...
- 移动4G插卡注网
本文根据插入移动4G单卡到注册4G网络过程的mtklog分析. 插卡动作: 从以上信息无法区分单卡还是双卡,通过ATR参数判断: 注网流程,此过程未开启4G数据连接: [MS->NW] ESM_ ...
- JavaScript正则表达式进阶指南
摘要:正则表达式是程序员的必备技能,想不想多学几招呢? 本文用JavaScript的exec方法来测试正则表达式. 例如,正则表达式**/F.*g/会匹配"以F开头,以g结尾的字符串&quo ...
- Shell基础 -Linux从入门到精通第九天(非原创)
文章大纲 一.关于shell二.shell进阶(重点)三.学习资料下载四.参考文章 一.关于shell 1. 什么是shell 1.1 shell简介 Shell(外壳) 是一个用 C 语言编写 ...
- VirtualBox打开VMware虚拟机
下载安装VirtualBox 打开VirtualBox,选择新建 设置如下: 之后就可以直接打开虚拟机了.
- Django框架(八)--单表增删改查,在Python脚本中调用Django环境
一.数据库连接配置 如果连接的是pycharm默认的Sqlite,不用改动,使用默认配置即可 如果连接mysql,需要在配置文件中的setting中进行配置: 将DATABASES={} 更新为 DA ...
- Linux下安装Nexus-3.15私服
1.切换到root用户 创建nexus用户:useradd nexus 设置nexus用户密码:passwd nexus 2.创建文件夹并进入该目录 linux中,软件包一般放在opt目录下,安装时, ...
- MySQL服务启动时显示本地计算机上的MySQL服务启动后停止。某些服务在。。。
之前一直用的好端端的,这次启动服务突然就报了这错误. 更好的阅读体验可访问 这里. 起因 为了使用 LOAD_FILE 函数,在数据库配置文件 my.ini的 [mysqld] 里添加 secure_ ...
- 如何让wordpress后台搜索只匹配搜索文章标题
今天编辑小美眉问网站wordpress后台能不能实现只搜索标题,这个问题怎么可能难到ytkah呢?打开Stack Overflow一顿狂搜,总数有解决方案了,哈哈哈!一起来看看怎么操作吧. 打开主题目 ...