以控制台程序为例引入以下来个程序集
Microsoft.Extensions.DependencyInjection
Microsoft.Extensions.DependencyInjection.Abstractions
1.创建服务和接口获取服务的基本使用
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);
}
}
2.创建服务和父类获取服务的基本使用
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.生命周期和作用域
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>();
}
}
4.释放容器
public static class Sample04
{
public interface IAccount{ }
public interface IMessage{ }
public interface ITool{ }
public class Base : IDisposable
{
public Base()
{
Console.WriteLine($"Created:{GetType().Name}");
}
public void Dispose()
{
Console.WriteLine($"Disposed: {GetType().Name}");
}
}
public class Account: Base, IAccount{}
public class Message:Base, IMessage{}
public class Tool:Base, ITool{}
public static void Run()
{
//释放根容器ITool
using (var root = new ServiceCollection()
.AddTransient<IAccount, Account>()
.AddScoped<IMessage, Message>()
.AddSingleton<ITool, Tool>()
.BuildServiceProvider())
{
//释放子容器IAccount,IMessage
using (var scope = root.CreateScope())
{
var child = scope.ServiceProvider;
child.GetService<IAccount>();
child.GetService<IMessage>();
child.GetService<ITool>();
Console.WriteLine("释放子容器");
}
Console.WriteLine("释放根容器");
}
}
}
5.类构造函数重载注入的选择
public static class Sample05
{
public interface IAccount{ }
public interface IMessage{ }
public interface ITool{ }
public interface ITest{ }
public class Account: IAccount{}
public class Message: IMessage{}
public class Tool: ITool{}
public class Test: ITest
{
// 如果某个构造函数的参数类型集合,能够称为所有合法构造函数参数类型集合的超集
// 那个这个构造函数就会被服务提供对象所选择。
public Test(IAccount account)
{
Console.WriteLine($"Ctor:Test(IAccount)");
}
//选这个前面服务注入了两个
public Test(IAccount account, IMessage message)
{
Console.WriteLine($"Ctor:Test(IAccount,IMessage)");
}
public Test(IAccount account, IMessage message, ITool tool)
{
Console.WriteLine($"Ctor:Test(IAccount,IMessage,ITool)");
}
}
public static void Run()
{
var test = new ServiceCollection()
.AddTransient<IAccount, Account>()
.AddTransient<IMessage, Message>()
.AddTransient<ITest, Test>()
.BuildServiceProvider()
.GetService<ITest>();
}
}
5.类构造函数重载注入的选择
多安装以下两个包
Autofac
Autofac.Extensions.DependencyInjection
替换自带依赖注入容器
public static class Sample02
{
public interface IAccount{ }
public interface IMessage{ }
public interface ITool{ }
public interface ITest
{
public IMessage Message { get; set; }
}
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 class Test: ITest
{
public IMessage Message { get; set; }
public Test(IAccount account, ITool tool)
{
Console.WriteLine($"Ctor:Test(IAccount, ITool)");
}
}
public static void Run()
{
var serviceCollection = new ServiceCollection()
.AddTransient<ITool, Tool>();
var containerBuilder = new ContainerBuilder();
containerBuilder.Populate(serviceCollection);
// 属性注入
containerBuilder.RegisterType<Test>().As<ITest>().PropertiesAutowired();
// 程序集注册
containerBuilder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
// 筛选基类为Base
.Where(t => t.BaseType == typeof(Base))
// 暴露第一个接口
.As(t => t.GetInterfaces()[0])
// 生命周期模式为Scope
.InstancePerLifetimeScope();
var container = containerBuilder.Build();
IServiceProvider provider = new AutofacServiceProvider(container);
Debug.Assert(provider.GetService<IAccount>() is Account);
Debug.Assert(provider.GetService<IMessage>() is Message);
Debug.Assert(provider.GetService<ITool>() is Tool);
var test = provider.GetService<ITest>();
Debug.Assert(test.Message is Message);
Console.Read();
}
}
使用
public static class Sample03
{
public interface IAccount{ }
public interface ITool{ }
public interface IMessageService { }
public class EmailMessageService : IMessageService
{
public IAccount Account { get; set; }
public ITool Tool { get; set; }
public EmailMessageService(IAccount account, ITool tool)
{
Account = account;
Tool = tool;
}
public void Test()
{
Console.WriteLine(Account.GetHashCode());
Console.WriteLine(Tool.GetHashCode());
}
}
public class SmsMessageService : IMessageService
{
public IServiceProvider ServiceProvider { get; set; }
public SmsMessageService(IServiceProvider serviceProvider)
{
ServiceProvider = serviceProvider;
}
public void Test()
{
Console.WriteLine(ServiceProvider.GetService<IAccount>().GetHashCode());
Console.WriteLine(ServiceProvider.GetService<ITool>().GetHashCode());
}
}
}