- 2016 年开始,分开了.NET Framework和.NET Core,后者开源、面向跨平台应用;
- 2019年,.NET Framework和.NET Core被.NET5完成了统一。未来只会有一个.NET,可以支持 Windows、Linux、macOS、iOS、Android、tvOS、watchOS 和 WebAssembly,等等
- .Net standard library 是之前.NET Framework和.NET Core公共的部分;
dotnet 组织包含了.NET Core的核心代码, 包括coreclr和corefx等.
- coreclr是运行时代码,
- corefx是各种基础类库的代码. CoreFX主要包含数个公共库,例如 System.Collections, System.IO, System.Xml等。
3. asp.net core
3.1. 3.1 Kestrel
Kestrel是asp.net core引入的跨平台的网络服务器,是默认配置。可以没有iis, apache和nginx就可以单独运行。
Kestrel基于libuv实现;(node.js 也是基于libuv)
3.2. 3.2 asp.net core 主要的特性
- 依赖注入。
- 日志系统架构。
- 引入了一个跨平台的网络服务器,kestrel。可以没有iis, apache和nginx就可以单独运行。
- 可以使用命令行创建应用。
- 使用AppSettings.json 来配置工程。
- 使用start up来注册服务。
- 更好的支持异步编程。
- 支持web socket和signal IR。
- 对于跨网站的请求的预防和保护机制。
3.3. 3.3 startup class的作用?
Startup class是dot net core应用的入口。所有的dot net core应用必须有这个class。这个类用来配置应用。这个类的调用是在program main函数里面进行配置的。类的名字可以自己定义。
3.4 Startup class的config service方法有什么作用?
在这个方法里我们可以添加一些service进入依赖注入容器。比如 数据库,swagger
3.5 startup class的configure方法有什么作用?
这个方法来定义整个应用如何响应HTTP请求。它有几个比较重要的参数,application builder,Hosting environment, logo factory, 在这里我们可以配置一些中间件用来处理路径,验证和session等等。
什么是meta packages?
Meta packages是指包含所有ASP dot net code依赖的一个包。叫做Microsoft.AspNetCore.All
3.7 什么是中间件?
中间件在这里是指注入到应用中处理请求和响应的组件。asp.net core 的中间件模型也是洋葱模型(和node.js d Koa 一样)
什么是中间件:
一个web应用程序都是把http请求封装成一个管道,一般来说每一次请求都要先经过管道的一系列操作,最终才到达我们的主程序中。中间件就是应用程序管道中的一个组件,用来拦截请求或进行一些其他处理和响应(比如验证用户身份是否合法、程序中是否有异常等等)。每一个中间件都可以对管道中的请求进行拦截,也有权决定是否把请求移交给下一个中间件。简而言之:中间件是用于组成程序管道来处理请求和响应的组件。与过滤器类似,都属于AOP应用。
在ASP.NET Core中,针对HTTP请求采用pipeline(管道)方式来处理,而管道容器内可以挂载很多中间件来处理HTTP请求,每一个中间件都有权决定是否需要执行下一个中间件,或者直接做出响应。这样的机制使得HTTP请求能够很好的被层层处理和控制,并且层次清晰处理起来方便。
3.8 application builder的use和run方法有什么区别?
这两个方法都在start up class的configure方法里面调用。都是用来向应用请求管道里面添加中间件的。Use方法可以调用下一个中间件的添加,而run不会。
3.9 dot net core 管道(pipeline)里面的map拓展有什么作用?
可以针对不同的路径添加不同的中间件。
public <span class="hljs-type">void</span> <span class="hljs-title function_">Configure</span><span class="hljs-params">(IApplicationBuilder app)</span>
{
app.Map(<span class="hljs-string">"/path1"</span>, Middleware1);
app.Map(<span class="hljs-string">"/path2"</span>, Middleware2);
}
3.10 如何在dot net core中激活session功能?
- 首先要添加session包.
- 其次要在config service方法里面添加session。
- 然后又在configure方法里面调用usesession。
3.11 如何在controller中注入service?
依赖注入的思想:
- 在config services方法中配置这个service。
- 在controller的构造函数中,添加这个依赖注入。
3.12 依赖注入后的服务生命周期?
在dot net core中,我们不需要关心如何释放这些服务, 因为系统会帮我们释放掉。有三种服务的生命周期。
- 单实例服务, 通过add singleton方法来添加。在注册时即创建服务, 在随后的请求中都使用这一个服务。
- 短暂服务, 通过add transient方法来添加。是一种轻量级的服务,用于无状态服务的操作。
- 作用域服务,一个新的请求会创建一个服务实例。使用add scoped方法来添加。()
小总结:
AddTransient瞬时模式:每次请求,都获取一个新的实例。即使同一个请求获取多次也会是不同的实例
AddScoped:每次请求,都获取一个新的实例。同一个请求获取多次会得到相同的实例
AddSingleton单例模式:每次都获取同一个实例
3.13 什么么是Razor页面?
是dot net core中支持ASP网页表格的一种开发模型。@page 作为页面的起始标志。可以看做是asp.net core使用的模板引擎。
Server.Transfer和Response.Redirect的区别是什么
- Server.Transfer仅是服务器中控制权的转向,在客户端浏览器地址栏中不会显示出转向后的地址;
- Response.Redirect则是完全的跳转,浏览器将会得到跳转的地址,并重新发送请求链接。这样,从浏览器的地址栏中可以看到跳转后的链接地址。
4. C#
4.1. 一个单例(Singleton)类
单线程下的简单实现:
public MySingleton
{
private <span class="hljs-title function_">MySingleton</span><span class="hljs-params">()</span>{} <span class="hljs-comment">// 禁止被实例化</span>
public readonly <span class="hljs-type">static</span> MySingletonInstance = new MySingleton(); <span class="hljs-comment">// 程序加载时就会初始化</span>
}
线程安全的加锁双检查
public <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MySingleton</span>
{</span>
private <span class="hljs-type">static</span> MySingleton _instance = null;
private <span class="hljs-type">static</span> readonly object SynObject = new object();
MySingleton() { }
public <span class="hljs-type">static</span> MySingleton Instance
{
get
{
<span class="hljs-keyword">if</span> (null == _instance)
{
lock (SynObject)
{
<span class="hljs-keyword">if</span> (null == _instance)
{
_instance = new MySingleton();
}
}
}
<span class="hljs-keyword">return</span> _instance;
}
}
}
4.2. abstract class和interface有什么区别?
相同点:都不能被直接实例化,都可以通过继承实现其抽象方法。
不同点:
- 接口支持多继承;抽象类不能实现多继承。
- 接口只能定义行为;抽象类既可以定义行为,还可能提供实现。
- 接口只包含方法(Method)、属性(Property)、索引器(Index)、事件(Event)的签名,但不能定义字段和包含实现的方法;
- 抽象类可以定义字段、属性、包含有实现的方法。
4.3. 是否可以继承String类?
String类是sealed类故不可以继承。
4.4. StringBuilder 和 String 的区别?
String 在进行运算时(如赋值、拼接等)会产生一个新的实例,而 StringBuilder 则不会。所以在大量字符串拼接或频繁对某一字符串进行操作时最好使用 StringBuilder,不要使用 String。
但是简单的字符拼接,String还是首选。(100?次以内用String,以上用StringBuilder)
4.6. string、String;int、Int32;Boolean、bool的区别
String、Int32、Boolean等都属于.Net中定义的类,而string、int、bool相当于C#中对这些类定义的别名。CTS。
.sring是关键字,String不是,String是类,具有类的特性
4.7. private、 protected、 public、 internal 修饰符的访问权限。
- private : 私有成员, 在类的内部才可以访问。
- protected : 保护成员,该类内部和继承类中可以访问。
- public : 公共成员,完全公开,没有访问限制。
- internal: 当前程序集内可以访问。
4.8. C#中的委托是什么?事件是不是一种委托?事件和委托的关系。
委托可以把一个方法作为参数代入另一个方法,可以理解为指向一个函数的指针。
换个说法来解释,委托就是函数指针,事件就是保存多个函数指针的数组。
事件和委托的区别如下:
- 事件只能在方法的外部进行声明,而委在方法的外部和内部都可以声明。
- 事件只能在类的内部触发,不能在类的外部触发。而委托在类的内部和外都都可以触发。
- 委托一般用于回调,而事件用于外部接口。例如在观察者模式中,在被观察者中可以声明一个事件作为外部观察者注册的接口。
4.9. override与重载(overload)的区别
- 重载是方法的名称相同。参数或参数类型不同,进行多次重载以适应不同的需要。重载(overload)是面向过程的概念。
- Override 是进行基类中函数的重写。Override是面向对象的概念
4.10. 什么是装箱(boxing)和拆箱(unboxing)
装箱:从值类型接口转换到引用类型。
拆箱:从引用类型转换到值类型。
什么是 IoC
IoC (Inversion of control )控制反转/反转控制。它是一种思想不是一个技术实现。描述的是: 对象的创建以及管理的问题。
例如:现有类 A 依赖于类 B
传统的开发方式 :往往是在类 A 中手动通过 new 关键字来 new 一个 B 的对象出来
使用 IoC 思想的开发方式 :不通过 new 关键字来创建对象,而是通过 IoC 容器( 框架) 来帮助我们实例化对象。我们需要哪个对象,直接从 IoC 容器里面取即可。.NET CORE通过构造函数取。
为什么叫控制反转
控制 :指的是对象创建(实例化、管理)的权力
反转 :控制权交给外部环境(Spring 框架、IoC 容器)
IoC 解决了什么问题
IoC 的思想就是两方之间不互相依赖,由第三方容器来管理相关资源。这样有什么好处呢?
对象之间的耦合度或者说依赖程度降低;
资源变的容易管理;
IoC 容器实际上就是个 Map(key,value),Map 中存放的是各种对象。
IoC 最常见以及最合理的实现方式叫做依赖注入(Dependency Injection,简称 DI)。
什么是Autofac依赖注入
一个自动 注入框架
什么是 AOP
AOP:Aspect oriented programming 面向切面编程,AOP 是 OOP(面向对象编程)的一种延续。
下面我们先看一个 OOP 的例子。
例如:现有三个类,Horse、Pig、Dog,这三个类中都有 eat 和 run 两个方法。
通过 OOP 思想中的继承,我们可以提取出一个 Animal 的父类,然后将 eat 和 run 方法放入父类中,Horse、Pig、Dog通过继承Animal类即可自动获得 eat() 和 run() 方法。这样将会少些很多重复的代码。
OOP 编程思想可以解决大部分的代码重复问题。但是有一些问题是处理不了的。比如在父类 Animal 中的多个方法的相同位置出现了重复的代码,OOP 就解决不了。
/**
* 动物父类
*/
<span class="keyword">public</span> class Animal {
/** 身高 */
private String height;
/** 体重 */
private <span class="keyword">double</span> weight;
<span class="keyword">public</span> void eat() {
// 性能监控代码
long start = System.currentTimeMillis();
// 业务逻辑代码
System.<span class="keyword">out</span>.println(<span class="string">"I can eat..."</span>);
// 性能监控代码
System.<span class="keyword">out</span>.println(<span class="string">"执行时长:"</span> + (System.currentTimeMillis() - start)/1000f + <span class="string">"s"</span>);
}
<span class="keyword">public</span> void run() {
// 性能监控代码
long start = System.currentTimeMillis();
// 业务逻辑代码
System.<span class="keyword">out</span>.println(<span class="string">"I can run..."</span>);
// 性能监控代码
System.<span class="keyword">out</span>.println(<span class="string">"执行时长:"</span> + (System.currentTimeMillis() - start)/1000f + <span class="string">"s"</span>);
}
}
这部分重复的代码,一般统称为 横切逻辑代码。
横切逻辑代码存在的问题:
- 代码重复问题
- 横切逻辑代码和业务代码混杂在一起,代码臃肿,不变维护
AOP 就是用来解决这些问题的
AOP 另辟蹊径,提出横向抽取机制,将横切逻辑代码和业务逻辑代码分离
代码拆分比较容易,难的是如何在不改变原有业务逻辑的情况下,悄无声息的将横向逻辑代码应用到原有的业务逻辑中,达到和原来一样的效果。
AOP 解决了什么问题
通过上面的分析可以发现,AOP 主要用来解决:在不改变原有业务逻辑的情况下,增强横切逻辑代码,根本上解耦合,避免横切逻辑代码重复。
AOP 为什么叫面向切面编程
切 :指的是横切逻辑,原有业务逻辑代码不动,只能操作横切逻辑代码,所以面向横切逻辑
面 :横切逻辑代码往往要影响的是很多个方法,每个方法如同一个点,多个点构成一个面。这里有一个面的概念
什么 是DDD?
DDD指view, application, domain, infrastructure,一种基础分层架构
1. UI
2. Application (service)
定义软件要完成的所有任务。
3.Domain (db, Repository)
业务
4. Infrastructure
关于Ocelot,Consul
============ 欢迎各位老板打赏~ ===========
与本文相关的文章
- · Asp.Net Core Filter 深入浅出的那些事-AOP
- · .NET Core使用Nlog记录日志
- · .netcore3返回JOSN首字母大写
- · .Net Core2.2升级到3.1
- · .NET Core微服务之基于Ocelot实现API网关服务
- · 利用阿里云快速安装最新版docker和加速docker pull
- · .NET中AOP的几种实现方案
- · 面向切面编程(AOP)的理解(一)
- · The instance of entity type ‘Customer’ cannot be tracked because another instance with the same key value for {‘Id’} is already being tracked.
- · .NET8实时更新nginx ip地址归属地
- · 解决.NET Blazor子组件不刷新问题
- · .NET8如何在普通类库中引用 Microsoft.AspNetCore