作者出书了,前面加了一节课,所有前面写的可能序号需要延后一次
P32:依赖注入的概念
服务定位器还是一种半自动化的,需要写代码实现去要的操作
依赖注入以后就可以直接使用了
P33:Net中的DI服务注册
服务类型尽量使用接口类型
基础服务代码
public interface ITestService { public string Name { get; set; } public void SayHi(); } public class TestEn : ITestService { public string Name { get; set; } public void SayHi() { Console.WriteLine("Say Hello"); } } public class TestCn : ITestService { public string Name { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } public void SayHi() { Console.WriteLine("你好"); } }
原始调用方式
Console.WriteLine("-------------原始调用----------------"); TestEn testEn = new TestEn(); testEn.SayHi();
DI调用方式
using Microsoft.Extensions.DependencyInjection; //00.using Microsoft.Extensions.DependencyInjection; //01.创建一个存放服务的集合 ServiceCollection services = new ServiceCollection();//查看源码,就是一个集合,一个服务的IList //02.在集合中添加一个服务 services.AddTransient<TestEn>(); //03.BuildServiceProvider 等于 服务定位器 using (ServiceProvider scope = services.BuildServiceProvider())//实现了IDisposable,所以必须用using,否则会资源泄露 { //04.跟服务定位器要一个服务 TestEn testEn1=scope.GetService<TestEn>(); //05.使用获得的服务 testEn1.Name = "lily"; testEn1.SayHi(); }
P34:服务的生命周期
//00.using Microsoft.Extensions.DependencyInjection; //01.创建一个存放服务的集合 ServiceCollection services = new ServiceCollection();//查看源码,就是一个集合,一个服务的IList //02.在集合中添加一个服务 //services.AddTransient<TestEn>();//瞬时,每次请求都是新的 //services.AddSingleton<TestEn>();//单例 services.AddScoped<TestEn>();//需要创建一个范围Scoped去使用 //03.BuildServiceProvider 等于 服务定位器 using (ServiceProvider sp = services.BuildServiceProvider())//实现了IDisposable,所以必须用using,否则会资源泄露 { ////04.跟服务定位器要一个服务 //TestEn testEn1=sp.GetService<TestEn>(); ////05.使用获得的服务 //testEn1.Name = "lily"; //testEn1.SayHi(); //TestEn testEn2 = sp.GetService<TestEn>(); //Console.WriteLine( object.ReferenceEquals(testEn1, testEn2));//比较两个变量是不是统一对象,是 true 否 false //testEn2.Name = "tom";//通过打印的方式验证,如果是同一对象,则会改变 //testEn1.SayHi(); //testEn2.SayHi(); TestEn ttt;//这里是为了演示,不要在外部使用作用域内的实例 using (IServiceScope scope1 = sp.CreateScope()) { //在scope中获取Scope相关的对象,scope1.ServiceProvider而不是sp TestEn t1 = scope1.ServiceProvider.GetService<TestEn>(); t1.Name = "lily"; t1.SayHi(); TestEn t2 = scope1.ServiceProvider.GetService<TestEn>(); Console.WriteLine(Object.ReferenceEquals(t1, t2)); t2.Name = "tom"; t1.SayHi(); t2.SayHi(); ttt = t1; } using (IServiceScope scope2 = sp.CreateScope()) { //在scope中获取Scope相关的对象,scope1.ServiceProvider而不是sp TestEn t1 = scope2.ServiceProvider.GetService<TestEn>(); t1.Name = "lily2"; t1.SayHi(); TestEn t2 = scope2.ServiceProvider.GetService<TestEn>(); Console.WriteLine(Object.ReferenceEquals(t1, t2)); t2.Name = "tom2"; t1.SayHi(); t2.SayHi(); Console.WriteLine(Object.ReferenceEquals(ttt, t2)); } }
P35:服务定位器
services.AddScoped<ITestService, TestCn>();//参数一 服务类型 参数二 实现类型 //services.AddScoped(typeof(ITestService),typeof(TestCn)); //services.AddSingleton<ITestService, TestCn>(); //services.AddSingleton(typeof(ITestService), new TestCn());//都可以,这里还可以传入参数 using(ServiceProvider sp = services.BuildServiceProvider()) { ITestService test = sp.GetService<ITestService>();//使用接口,与前面的服务类型要一致,前面是接口这里就是接口,前面是类,这里就是类,GetService如果找不到服务就返回null
//ITestService test2 = (ITestService)sp.GetService(typeof(ITestService));//非泛型的获取方法,一般用不着
test.Name = "Eric"; test.SayHi();
}
services.AddScoped<ITestService, TestCn>();//参数一 服务类型 参数二 实现类型 services.AddScoped<ITestService, TestEn>();//参数一 服务类型 参数二 实现类型 //services.AddScoped(typeof(ITestService),typeof(TestCn)); //services.AddSingleton<ITestService, TestCn>(); //services.AddSingleton(typeof(ITestService), new TestCn());//都可以,这里还可以传入参数 using(ServiceProvider sp = services.BuildServiceProvider()) { ITestService test = sp.GetService<ITestService>();//使用接口,与前面的服务类型要一致,前面是接口这里就是接口,前面是类,这里就是类,GetService如果找不到服务就返回null test.Name = "Eric"; test.SayHi(); //ITestService test2 = (ITestService)sp.GetService(typeof(ITestService));//非泛型的获取方法,一般用不着 //TestCn testCn = sp.GetRequiredService<TestCn>();//Required必须的,如果找不到就抛异常,不返回null Console.WriteLine("-----------------------------"); IEnumerable<ITestService> testList = sp.GetServices<ITestService>();//多个服务 foreach(ITestService t in testList) { Console.WriteLine(t.GetType()); } Console.WriteLine("-----------------------------"); //如果存在多个服务但是使用了GetService获取,会得到最后一个注入的服务 ITestService test1 = sp.GetService<ITestService>(); Console.WriteLine(test1.GetType()); }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!