【asp.net core 系列】14 .net core 中的IOC
0.前言
通过前面几篇,我们了解到了如何实现项目的基本架构:数据源、路由设置、加密以及身份验证。那么在实现的时候,我们还会遇到这样的一个问题:当我们业务类和数据源越来越多的时候,我们无法通过普通的构造对象的方法为每个实例进行赋值。同时,传统意义上的赋值遇到底层切换或者其他修改的时候,就需要修改大量的代码,对改变不友好。为了改变这种现状,我们基于面向接口编程,然后使用一些DI功能和IOC框架。
1. IOC和DI
先来给大家解释几个概念,IOC全称Inversion of Control,翻译过来就是控制反转,是面向对象编程的一种设计原则,用来降低代码之间的耦合度。所谓的控制反转简单来讲就是将类中属性或者其他参数的初始化交给其他方处理,而不是直接使用构造函数。
public class Demo1
{
}public class Demo2
{public Demo1 demo;
}
对于以上简单示例代码中,在Demo2类中持有了一个Demo1的实例。如果按照之前的情况来讲,我们会通过以下方法为demo赋值:
// 方法一
public Demo1 demo = new Demo1();
// 方法二
public Demo2()
{demo = new Demo1();
}
这时候,如果Demo1变成下面的样子:
public class Demo1
{public Demo1(Demo3 demo3){// 隐藏}
}
public class Demo3
{
}
那么,如果Demo2 没有持有一个Demo3的实例对象,这时候创建Demo1的时候就需要额外构造一个Demo3。如果Demo3需要持有另外一个类的对象,那么Demo2中就需要多创建一个对象。最后就会发现这样就陷入了一个构造“地狱”(我发明的词,指这种为了一个对象却得构造一大堆其他类型的对象)。
实际上,对于Demo2并不关心Demo1的实例对象是如何获取的,甚至都不关心它是不是Demo1的子类或者接口实现类。我在示例中使用了类,但这里可以同步替换成Interface,替换之后,Demo2在调用Demo1的时候,还需要知道Demo1有实现类,以及实现类的信息。
为了解决这个问题,一些高明的程序员们提出了将对象的创建这一过程交给第三方去操作,而不是调用类来创建。于是乎,上述代码就变成了:
public class Demo2
{public Demo1 Demo {get;set;}public Demo2(Demo1 demo){Demo = demo;}
}
似乎并没有什么变化?对于Demo2来说,Demo2从此不再负责Demo1的创建,这个步骤交由Demo2的调用方去创建,Demo2从此从负责维护Demo1这个对象的大麻烦中解脱了。
但实际上构造地狱的问题还是没有解决,只不过是通过IOC的设计将这一步后移了。这时候,那些大神们想了想,不如开发一个框架这些实体对象吧。所以就出现了很多IOC框架:AutoFac、Sping.net、Unity等。
说到IOC就不得不提一下DI(Dependency Injection)依赖注入。所谓的依赖注入就是属性对应实例通过构造函数或者使用属性由第三方进行赋值。也就是最后Demo2的示例代码中的写法。
早期IOC和DI是指一种技术,后来开始确定这是不同的描述。IOC描述的是一种设计模式,而DI是一种行为。
2. 使用asp.net core的默认IOC
在之前的ASP.NET 框架中,微软并没有提供默认的IOC支持。在最新的asp.net core中微软提供了一套IOC支持,该支持在命名空间:
Microsoft.Extensions.DependencyInjection
里,在代码中引用即可。
主要通过以下几组方法实现:
public static IServiceCollection AddScoped<TService>(this IServiceCollection services) where TService : class;
public static IServiceCollection AddSingleton<TService>(this IServiceCollection services) where TService : class;
public static IServiceCollection AddTransient<TService>(this IServiceCollection services) where TService : class;
这里只列出了这三组方法的一种重载版本。
这三组方法分别代表三种生命周期:
- AddScored 表示对象的生命周期为整个Request请求
- AddTransient 表示每次从服务容器进行请求时创建的,适合轻量级、 无状态的服务
- AddSingleton 表示该对象在第一次从服务容器请求后获取,之后就不会再次初始化了
这里每组方法只介绍了一个版本,但实际上每个方法都有以下几个版本:
public static IServiceCollection AddXXX<TService>(this IServiceCollection services) where TService : class;
public static IServiceCollection AddXXX(this IServiceCollection services, Type serviceType, Type implementationType);
public static IServiceCollection AddXXX(this IServiceCollection services, Type serviceType, Func<IServiceProvider, object> implementationFactory);
public static IServiceCollection AddXXX<TService, TImplementation>(this IServiceCollection services)where TService : classwhere TImplementation : class, TService;
public static IServiceCollection AddXXX(this IServiceCollection services, Type serviceType);
public static IServiceCollection AddXXX<TService>(this IServiceCollection services, Func<IServiceProvider, TService> implementationFactory) where TService : class;
public static IServiceCollection AddXXX<TService, TImplementation>(this IServiceCollection services, Func<IServiceProvider, TImplementation> implementationFactory)where TService : classwhere TImplementation : class, TService;
其中:implementationFactory 表示通过一个Provider实现TService/TImplementation 的工厂方法。当方法指定了泛型的时候,会自动依据泛型参数获取要注入的类型信息,如果没有使用泛型则必须手动传入参数类型。
asp.net core如果使用依赖注入的话,需要在Startup方法中设置,具体内容可以参照以下:
public void ConfigureServices(IServiceCollection services)
{//省略其他代码services.AddScoped<ISysUserAuthRepository,SysUserAuthRepository>();
}
asp.net core 为DbContext提供了不同的IOC支持,AddDbContext:
public static IServiceCollection AddDbContext<TContext>(this IServiceCollection serviceCollection,Action<DbContextOptionsBuilder> optionsAction = null,ServiceLifetime contextLifetime = ServiceLifetime.Scoped,ServiceLifetime optionsLifetime = ServiceLifetime.Scoped)where TContext : DbContext;
使用方法如下:
services.AddDbContext<DefaultContext>();
3. AutoFac 使用
理论上,asp.net core的IOC已经足够好了,但是依旧原谅我的贪婪。如果有二三百个业务类需要我来设置的话,我宁愿不使用IOC。因为那配置起来就是一场极其痛苦的过程。不过,可喜可贺的是AutoFac可以让我免收这部分的困扰。
这里简单介绍一下如何使用AutoFac作为IOC管理:
cd Web # 切换目录到Web项目
dotnet package add Autofac.Extensions.DependencyInjection # 添加 AutoFac的引用
因为asp.net core 版本3更改了一些逻辑,AutoFac的引用方式发生了改变,现在不介绍之前版本的内容,以3为主。使用AutoFac需要先在 Program类里设置以下代码:
public static IHostBuilder CreateHostBuilder(string[] args) =>Host.CreateDefaultBuilder(args).UseServiceProviderFactory(new AutofacServiceProviderFactory()) // 添加这行代码.ConfigureWebHostDefaults(webBuilder =>{webBuilder.UseStartup<Startup>();});
在Program类里启用AutoFac的一个Service提供工厂类。然后在Startup类里添加如下方法:
public void ConfigureContainer(ContainerBuilder builder)
{builder.RegisterType<DefaultContext>().As<DbContext>().WithParameter("connectStr","Data Source=./demo.db").InstancePerLifetimeScope();builder.RegisterAssemblyTypes(Assembly.Load("Web")).Where(t => t.BaseType.FullName.Contains("Filter")).AsSelf();builder.RegisterAssemblyTypes(Assembly.Load("Domain"),Assembly.Load("Domain.Implements"), Assembly.Load("Service"), Assembly.Load("Service.Implements")).AsSelf().AsImplementedInterfaces().InstancePerLifetimeScope().PropertiesAutowired();
}
修改:
public void ConfigureServices(IServiceCollection services)
{services.AddControllersWithViews(options =>{options.Filters.Add<UnitOfWorkFilterAttribute>();}).AddControllersAsServices();// 这行新增// 省略其他
}
4. 总结
这一篇简单介绍了如何在Asp.net Core中启用IOC支持,并提供了两种方式,可以说是各有优劣。小伙伴们根据自己需要选择。后续会为大家详细深入AutoFac之类IOC框架的核心秘密。
更多内容烦请关注我的博客《高先生小屋》
【asp.net core 系列】14 .net core 中的IOC相关推荐
- 精通Server Core系列之一 ---Server Core简介
和Windows Server 2003不一样的是, 从Windows Server 2008 开始,我们可以安装只具有特定功能最小安装服务器核心(Server Core)版本,它为一些特定服务的正常 ...
- .ne中的控制器循环出来的数据如何显示在视图上_【asp.net core 系列】3 视图以及视图与控制器...
0.前言 在之前的几篇中,我们大概介绍了如何创建一个http://asp.net core mvc项目以及http请求如何被路由转交给对应的执行单元.这一篇我们将介绍一下控制器与视图直接的关系. 1. ...
- 5.3Role和Claims授权「深入浅出ASP.NET Core系列」
5.3Role和Claims授权「深入浅出ASP.NET Core系列」 原文:5.3Role和Claims授权「深入浅出ASP.NET Core系列」 希望给你3-5分钟的碎片化学习,可能是坐地铁. ...
- asp.net core系列 38 WebAPI 返回类型与响应格式--必备
一.返回类型 ASP.NET Core 提供以下 Web API Action方法返回类型选项,以及说明每种返回类型的最佳适用情况: (1) 固定类型 (2) IActionResult (3) Ac ...
- 5.1基于JWT的认证和授权「深入浅出ASP.NET Core系列」
原文:5.1基于JWT的认证和授权「深入浅出ASP.NET Core系列」 希望给你3-5分钟的碎片化学习,可能是坐地铁.等公交,积少成多,水滴石穿,码字辛苦,如果你吃了蛋觉得味道不错,希望点个赞,谢 ...
- ASP.NET CORE系列【一】搭建ASP.NET CORE项目
原文:ASP.NET CORE系列[一]搭建ASP.NET CORE项目 为什么要使用 ASP.NET Core? NET Core 刚发布的时候根据介绍就有点心里痒痒,微软的尿性都懂的,新东西bug ...
- asp.net core 系列 18 web服务器实现
一. ASP.NET Core Module 在介绍ASP.NET Core Web实现之前,先来了解下ASP.NET Core Module.该模块是插入 IIS 管道的本机 IIS 模块(本机是指 ...
- asp向不同的用户发送信息_【asp.net core 系列】 1 带你了解一下asp.net core
0. 前言 这是一个新的系列,名字是<http://ASP.NET Core 入门到实战>.这个系列主讲http://ASP.NET Core MVC,辅助一些前端的基础知识(能用来实现我 ...
- .NET Core 3.0 Preview 3中关于ASP.NET Core的更新内容
.NET Core 3.0 Preview 3已经推出,它包含了一系列关于ASP.NET Core的新的更新. 下面是该预览版的更新列表: Razor组件改进: 单项目模板 新的Razer扩展 End ...
最新文章
- Redis数据类型:散列类型
- 使用UML描述需求都实现的过程
- YOLOX——Win10下训练自定义VOC数据集
- Kafka使用遇到的坑
- 四级计算机网络考试大纲,2017年全国计算机等级考试四级计算机网络考试大纲...
- 蛋白质:结构和功能 Proteins: Structure and Function
- OpenCASCADE:MFC示例
- Web.xml配置Error Page不能够转发的问题分析及解决
- 02-1.CSS边框,边界,布局相关笔记
- php 其他页面获取session_PHP安全:XSS漏洞防御
- 优达学城深度学习之三(上)——卷积神经网络
- Android 相对布局常用属性
- 腾讯、阿里、字节竟然是这么做数据库的?!
- JavaScript高级程序设计(第4版)知识点总结
- 可怕!让无数女明星下海的换脸术来了,Facebook推出视频换脸功能!
- Chrome 离线下载最佳方法
- 自媒体运营,你要的小工具来了
- verlay虚拟化技术_Overlay之VXLAN架构
- 【分享】VMwareESXI详细黑群晖教程 DS36156
- 飘云QQ宣布终止后续开发 称不懂游戏规则玩不起