什么是依赖关系注入?
依赖关系注入是控制反转 (IoC
) 模式的专用版本,其中要反转的问题是获取所需依赖项的过程。 使用依赖关系注入时,另一个类负责在运行时将依赖项注入对象。
案例
记录日志功能,先记录到控制台,再记录到物理文件,对比改造过程;
面向对象的实现
1 2 3 4 5 6 7
| public class ConsoleLogger { public void Write(string msg) { Console.WriteLine(msg); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| public class Account { public void Login() { ConsoleLogger logger = new ConsoleLogger(); logger.Write("登录中的日志...."); } public void Logout() { ConsoleLogger logger = new ConsoleLogger(); logger.Write("登出中的日志...."); } }
|
改造方案:需要把所有的 ConsoleLogger logger = new ConsoleLogger();
替换掉
缺点:
- 工作量大
- 重复性动作
- 代码改动位置多,都需要重新测试
面向接口+工厂模式的实现
1 2 3 4
| public interface ILogger { void Write(string msg); }
|
1 2 3 4 5 6 7
| public class ConsoleLogger : ILogger { public void Write(string msg) { Console.WriteLine(msg); } }
|
1 2 3 4 5 6 7
| public class LoggerFactory { public static ILogger CreateLogger() { return new ConsoleLogger(); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| public class Account { public void Login() { ILogger logger = LoggerFactory.CreateLogger(); logger.Write("登录中的日志...."); } public void Logout() { ILogger logger = LoggerFactory.CreateLogger(); logger.Write("登出中的日志...."); } }
|
改造方案:需要把 LoggerFactory.CreateLogger
中的 new ConsoleLogger();
替换掉
缺点:
- 每个类都需要实现自己的工厂模式,不利于维护
依赖注入实现
Microsoft.Extensions.DependencyInjection
1 2 3 4
| public interface ILogger { void Write(string msg); }
|
1 2 3 4 5 6 7
| public class ConsoleLogger : ILogger { public void Write(string msg) { Console.WriteLine(msg); } }
|
1 2 3 4 5 6 7
| IServiceCollection serviceCollection = new ServiceCollection(); serviceCollection.AddScoped<ILogger, ConsoleLogger>(); using (ServiceProvider serviceProvider = serviceCollection.BuildServiceProvider()) { ILogger logger = serviceProvider.GetService<ILogger>(); logger.Write("我是日志内容..."); }
|