如何用Simple Injector实现依赖注入?控制台应用DI疑问求解
解决控制台应用中依赖注入的手动传参问题
嘿,完全懂你的感受!从ASP.NET Core那种“注册完服务就不用管,构造函数自动拿依赖”的模式切换到控制台手动传参,尤其是服务多了之后,确实会觉得繁琐又容易出错。其实你用的SimpleInjector完全支持类似ASP.NET Core的自动构造注入,只是你现在还没用到它的这个核心能力而已。
问题出在哪?
你现在的做法是手动从容器获取ILogger,然后自己new MainAgent(log)——这相当于跳过了容器的自动解析能力,自然要手动传所有依赖。如果后续MainAgent需要新增其他服务(比如IConfigService、IDataAccess),你就得每次都修改new的代码,传一堆参数,这显然不是长久之计。
正确的做法:让容器帮你解析MainAgent
SimpleInjector的核心就是自动解析构造函数依赖,只要你把MainAgent也注册到容器里,然后直接从容器获取它的实例,容器就会自动把所有构造函数需要的依赖(比如ILogger)注入进去,和ASP.NET Core控制器的逻辑一模一样。
修改后的代码如下:
Program类:
static void Main(string[] args) { var container = new SimpleInjector.Container(); // 1. 注册所有服务(包括你的业务类MainAgent) container.Register<ILogger, FileLogger>(); container.Register<MainAgent>(); // 新增这行,把MainAgent也交给容器管理 // 2. 验证容器(非常重要!提前发现依赖缺失或配置错误) container.Verify(); // 3. 直接从容器获取MainAgent实例,不用手动传参! ILogger log = container.GetInstance<ILogger>(); log.Info("Logging From Main Method"); MainAgent agent = container.GetInstance<MainAgent>(); // 这里改了 agent.Start(); }
MainAgent类(不需要任何修改,建议优化字段修饰符):
public class MainAgent { private readonly ILogger _log; // 用readonly修饰,确保依赖不会被意外修改 public MainAgent(ILogger log) { _log = log; } public void Start() { Console.WriteLine("main Agent Started."); _log.Info("Logging through logger in MainAgent Class"); Console.ReadLine(); } }
为什么这样可行?
当你调用container.GetInstance<MainAgent>()时,SimpleInjector会:
- 检查
MainAgent的构造函数,发现它需要一个ILogger - 自动从容器中取出已经注册好的
FileLogger实例 - 用这个实例创建
MainAgent对象,返回给你
哪怕后续MainAgent的构造函数新增了10个依赖,只要你把这些依赖都注册到容器里,SimpleInjector都会自动处理,你完全不用改GetInstance的代码——这和ASP.NET Core控制器的注入逻辑完全一致。
额外建议
- 尽量避免手动
new需要依赖的类,除非是完全不需要任何服务的纯数据类 - 始终调用
container.Verify(),它会提前验证所有注册的服务是否能被正确解析,避免运行时出现“找不到依赖”的错误 - 如果有多个根服务(比如除了
MainAgent还有其他启动类),同样可以通过容器获取它们的实例
内容的提问来源于stack exchange,提问作者tornup
相关产品推荐
相关产品推荐

