服务容器,应用的服务提供者,.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 保存在根容器 只有当根容器的释放才会释放!