.NetCore内置IOC容器ServiceCollection一、IOC介绍IOC:全名(
Inversion of Control
)-控制反转
IOC意味着我们将对象的创建控制权交给了外部容器,我们不管它是如何创建的,我们只需要知道,当我们想要某个实例时,我们可以直接从这个外部容器中去拿,而再也不需要我们去new了,充分体现了DIP(依赖倒置原则),也体现了我们经常挂在嘴边的面向接口编程。
DI:全名(
Dependency Injection
)-依赖注入
DI意味着将类型之间的依赖关系注入到DI容器中
在之前的
.Net Framework
中并没有集成
IOC
,虽然Microsoft自己有一套"Unity",想要使用IOC+DI时,还需要我们自己去安装包,进行三部曲等等各种操作
比较流行的IOC容器技术:Autofac、Unity、NInject。。。
二、.NetCore内置IOC容器ServiceCollection1、打开NuGet包管理器,安装
Microsoft.Extensions.DependencyInjection
包
2、实现代码如下:
public interface ISqlHelper{ void GetAll();}public class SqlServerHelper : ISqlHelper{ public void GetAll() { Console.WriteLine("this is "+typeof(SqlServerHelper)); }}static void Main(string[] args){ ServiceCollection services = new ServiceCollection(); services.AddTransient(); var provider=services.BuildServiceProvider(); var sqlHelper=provider.GetService(); sqlHelper.GetAll(); Console.ReadKey();}
运行结果输出:
this is SqlServerHelper
当我们在执行业务逻辑时想要写入一些日志(
Log
),必然会当然依赖这个类,那么会形成了
SqlHelper
类与
Log
类之前的依赖关系,我们可以将之前的依赖关系转移到
DI
容器中,也就是依赖注入(
DI
),然后在
DI
容器获取服务(对象)
示例代码如下:
public interface ISqlHelper { void GetAll();}public class SqlServerHelper : ISqlHelper { private readonly ILog _ilog; public SqlServerHelper(ILog ilog) { _ilog = ilog; } public void GetAll() { _ilog.LogInfo($"我在{typeof(SqlServerHelper).Name}中,我是ilog"); Console.WriteLine("this is " + typeof(SqlServerHelper).Name); }}public interface ILog { void LogInfo(string msg);}public class Log : ILog { public void LogInfo(string msg) { Console.WriteLine(msg); }}private static void Main(string[] args) { services.AddTransient();//瞬时注入 services.AddTransient();//瞬时,每次的实例都是一个新的对象 var provider = services.BuildServiceProvider();//构建服务提供商 var sqlHelper = provider.GetService();//获取我们需要的服务实例 sqlHelper.GetAll(); Console.ReadKey();}
如果如下:
我在SqlServerHelper中,我是ilogthis is SqlServerHelper
三、组件的生命周期1、
Transient
:瞬时,每次的实例都是一个新的对象
3、
Scoped
:作用域,在一个作用域中唯一实例,比如在
Asp.Net Core
应用程序中一次请求相当于一个
Scoped
Transient:瞬时,每次的实例都是一个新的对象ServiceCollection services = new ServiceCollection();services.AddTransient();services.AddTransient();var provider = services.BuildServiceProvider();var sqlHelper = provider.GetService();//首次获取要使用的服务sqlHelper = provider.GetService();//获取新的服务sqlHelper.GetAll();
结果如下:
Singleton:单例,全局唯一实例ServiceCollection services = new ServiceCollection();services.AddSingleton();services.AddSingleton();var provider = services.BuildServiceProvider();var sqlHelper = provider.GetService();sqlHelper = provider.GetService();sqlHelper.GetAll();Console.ReadKey();
Scoped:作用域,在一个作用域中唯一实例一个作用域
ServiceCollection services = new ServiceCollection();services.AddScoped();services.AddScoped();var provider = services.BuildServiceProvider();var scope1 = provider.CreateScope();//在一个作用域下创建第一个子作用域 var sqlHelper = scope1.ServiceProvider.GetService();
新的作用域
ServiceCollection services = new ServiceCollection();services.AddScoped();services.AddScoped();var provider = services.BuildServiceProvider();var scope1 = provider.CreateScope();//在一个作用域下创建第一个子作用域 var sqlHelper = scope1.ServiceProvider.GetService();var scope2 = provider.CreateScope();//在一个作用域下创建第二个子作用域sqlHelper = scope2.ServiceProvider.GetService();
注意:由于是控制台项目,只能用子作用域来体现作用域的特点,在web项目中,一次请求就相当于一个作用域
推荐阅读资料参考• ServiceCollection 类 (Microsoft.Extensions.DependencyInjection) | Microsoft Learn [1]
• ASP.NET Core 中的 ServiceProvider - hippieZhou - 博客园 [2]
欢迎关注我的公众号“Net分享”,技术文章第一时间推送 , 分享一些你可能注意不到的细节。
引用链接[1]
ServiceCollection 类 (Microsoft.Extensions.DependencyInjection) | Microsoft Learn:
https://learn.microsoft.com/zh-cn/dotnet/api/microsoft.extensions.dependencyinjection.servicecollection?view=dotnet-plat-ext-6.0 [2] :
https://blog.csdn.net/m1m2m3mmm/article/details/123231352