作者出书了,前面加了一节课,所有前面写的可能序号需要延后一次

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());
}