(精华)2020年12月24日 .NET Core 自带依赖注入的实现原理
【摘要】
以控制台程序为例引入以下来个程序集
Microsoft.Extensions.DependencyInjection
Microsoft.Extensions.DependencyInjection.A...
以控制台程序为例引入以下来个程序集
Microsoft.Extensions.DependencyInjection
Microsoft.Extensions.DependencyInjection.Abstractions
- 1
- 2
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);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
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());
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
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>();
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
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("释放根容器");
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
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>();
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
5.类构造函数重载注入的选择
多安装以下两个包
Autofac
Autofac.Extensions.DependencyInjection
- 1
- 2
替换自带依赖注入容器
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();
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
使用
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());
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
文章来源: codeboy.blog.csdn.net,作者:愚公搬代码,版权归原作者所有,如需转载,请联系作者。
原文链接:codeboy.blog.csdn.net/article/details/108412716
【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)