.Net Core-依赖注入框架

  服务容器,应用的服务提供者,.net core 最基本的编程模式

  .NET Core 有一个内置的依赖注入框架。包:Microsoft.Extensions.DependencyInjection   Microsoft.Extensions.DependencyInjection.Abstractions

   很多组件框架都是来自于.net 拓展 

    使用 ServiceCollection 服务对象 可以设置对应的生命周期 ,BuildServiceProvider创建服务提供对象 GetService获取响应服务的实例

    AddTransient (瞬时)  AddScoped (作用域) AddSingleton(单例) 注册服务的方法

    可以为同一个类添加多个服务,但是不管你添加多少个 GetService 还是会返回一个

具体实现演变:

复制代码

public static class Sample01
{
  public interface IAccount{ }
  public interface IMessage{ }
  public interface ITool{ }

  public class Account: IAccount{}
  public class Message: IMessage{}
  public class Tool: ITool{}

 public static void Run()
 {
   var provider = new ServiceCollection()
   .AddTransient<IAccount, Account>()
   .AddScoped<IMessage, Message>()
   .AddSingleton<ITool, Tool>()
   .BuildServiceProvider();

   Debug.Assert(provider.GetService<IAccount>() is Account);
   Debug.Assert(provider.GetService<IMessage>() is Message);
   Debug.Assert(provider.GetService<ITool>() is Tool);
 }
}

复制代码

注册相同的例子:

复制代码

public static class Sample02
{
  public interface IAccount{ }
  public interface IMessage{ }
  public interface ITool{ }

  public class Base
  {
     public Base()
    {
     Console.WriteLine($"{GetType().Name} 已创建");
     }
   } 

  public class Account:Base, IAccount{}
  public class Message:Base, IMessage{}
  public class Tool:Base, ITool{}

 public static void Run()
 {
   var services = new ServiceCollection()
   .AddTransient<Base, Account>()
   .AddTransient<Base, Message>()
   .AddTransient<Base, Tool>()
   .BuildServiceProvider()
   .GetServices<Base>().ToList();

   Debug.Assert(services.OfType<Account>().Any());
   Debug.Assert(services.OfType<Message>().Any());
   Debug.Assert(services.OfType<Tool>().Any());
 }
}

复制代码

 

    3钟生命周期   AddTransient (瞬时)  AddScoped (作用域) AddSingleton(单例):支持子容器,服务提供对象,代码了框架中的容器   CreateScope创建服务范围

    单例模式:根容器的服务提供对象上的,所有同根的子容器可以共享这个单例对象

    作用域模式:当前的服务提供对象,保证当前的容器范围内提供的实例单例,也就是子容器的范围  (在子容器的)

    瞬时模式:没有生命周期,一次性的!

   演示三种生命周期的例子:

复制代码

public static class Sample03
{
  public interface IAccount{ }
  public interface IMessage{ }
  public interface ITool{ }

  public class Base
  {
  public Base()
  {
  Console.WriteLine($"Created:{GetType().Name}");
  }

}

  public class Account: Base, IAccount{}
  public class Message:Base, IMessage{}
  public class Tool:Base, ITool{}

  public static void Run()
  {
    var root = new ServiceCollection()
    .AddTransient<IAccount, Account>()
    .AddScoped<IMessage, Message>()
    .AddSingleton<ITool, Tool>()
    .BuildServiceProvider();

   var child1 = root.CreateScope().ServiceProvider;//获取子容器
   var child2 = root.CreateScope().ServiceProvider; //获取子容器

   GetService<IAccount>(child1);
   GetService<IMessage>(child1);
   GetService<ITool>(child1);
   Console.WriteLine();
   GetService<IAccount>(child2);
   GetService<IMessage>(child2);
   GetService<ITool>(child2);
  }

  public static void GetService<T>(IServiceProvider provider)
  {
   provider.GetService<T>();
   provider.GetService<T>();
  }
}

复制代码

 运行结果:

 

 可以创建服务示例如何管理这些服务示例 如何释放呢?释放策略

  瞬时域模式和作用域模式如果接口实现IDisposable,当前的服务提供对象也实现了IDisposable,所以先调用服务对象的IDisposable,一起调用。

  如果是单例的生命周期 ,他的IDisposable 保存在根容器 只有当根容器的释放才会释放!

  思考:ASP.NET Core 应用,具有一个与当前应用所绑定的代表全局根容器的服务提供对象处理请求,使用根容器,每当有一个请求进来,创建这个请求对应的服务范围(根容器的子容器=请求),处理请求所需的服务实例。

   请求处理完以后,服务范围被终结,作用域的实例,实现了IDisaable 接口的瞬时服务,都会被释放!

  

例子:

复制代码

public static class Sample03
{
  public interface IAccount{ }
  public interface IMessage{ }
  public interface ITool{ }

  public class Base
  {
  public Base()
  {
  Console.WriteLine($"Created:{GetType().Name}");
  }

}

  public class Account: Base, IAccount{}
  public class Message:Base, IMessage{}
  public class Tool:Base, ITool{}

  public static void Run()
  {
    var root = new ServiceCollection()
    .AddTransient<IAccount, Account>()
    .AddScoped<IMessage, Message>()
    .AddSingleton<ITool, Tool>()
    .BuildServiceProvider();

   var child1 = root.CreateScope().ServiceProvider;//获取子容器
   var child2 = root.CreateScope().ServiceProvider; //获取子容器

   GetService<IAccount>(child1);
   GetService<IMessage>(child1);
   GetService<ITool>(child1);
   Console.WriteLine();
   GetService<IAccount>(child2);
   GetService<IMessage>(child2);
   GetService<ITool>(child2);
  }

  public static void GetService<T>(IServiceProvider provider)
  {
   provider.GetService<T>();
   provider.GetService<T>();
  }
}

复制代码

 运行结果:

 

 总结:作用域的服务对象是跟着(子容器)作用域销毁的,瞬时的服务对象是如果实现了IDisable会跟(子容器)作用域销毁,

但是如果没有实现IDisable瞬时就是什么时候用完什么时候立即销毁,单例的服务对象会跟着子容器的的释放而销毁!

 

    

   

posted @   根仔  阅读(266)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示