如何在Windows服务类中获取当前IUnityContainer以注册更多类型
嘿,我来帮你搞定这个Unity 2.1 Windows服务的容器获取问题——要在服务类里拿到IUnityContainer来注册类型,有两个实用方案,我给你详细说说:
方案1:用静态容器实例(简单直接,快速上手)
这种方式最容易实现,适合不想大改现有代码的场景。你只需要在Program.cs里把初始化好的容器存为静态属性,之后在服务类里直接调用就行。
步骤1:在Program.cs中定义静态容器
public static class Program { // 静态容器实例,供全局访问 public static IUnityContainer Container { get; private set; } static void Main() { // 初始化Unity容器 Container = new UnityContainer(); // 先注册服务启动需要的基础类型 Container.RegisterType<ISomeCoreService, SomeCoreServiceImpl>(); // 启动Windows服务 ServiceBase[] ServicesToRun = new ServiceBase[] { new MyCustomWindowsService() }; ServiceBase.Run(ServicesToRun); } }
步骤2:在服务类中使用静态容器
public class MyCustomWindowsService : ServiceBase { protected override void OnStart(string[] args) { // 直接通过静态属性拿到容器,注册新类型 Program.Container.RegisterType<INewFeatureService, NewFeatureServiceImpl>(); // 注册完成后就可以正常解析使用了 var featureService = Program.Container.Resolve<INewFeatureService>(); featureService.InitializeFeature(); } }
优缺点:优点是零学习成本,代码改动极小;缺点是引入了静态依赖,稍微破坏了依赖注入的封装性,但对于Windows服务这种单实例启动的场景,完全够用。
方案2:构造函数注入容器(更符合DI最佳实践)
如果你想遵循依赖注入的设计原则,避免静态依赖,推荐用这个方案。核心思路是在Program.cs里用Unity容器解析服务类实例,让容器自动把自身注入到服务类的构造函数中。
步骤1:修改Program.cs的服务启动逻辑
public static class Program { public static IUnityContainer Container { get; private set; } static void Main() { Container = new UnityContainer(); // 注册基础类型,同时把服务类本身也注册到容器中 Container.RegisterType<ISomeCoreService, SomeCoreServiceImpl>(); Container.RegisterType<MyCustomWindowsService>(); // 用Unity解析服务类实例,容器会自动注入IUnityContainer var serviceInstance = Container.Resolve<MyCustomWindowsService>(); ServiceBase[] ServicesToRun = new ServiceBase[] { serviceInstance }; ServiceBase.Run(ServicesToRun); } }
步骤2:在服务类中接收注入的容器
public class MyCustomWindowsService : ServiceBase { private readonly IUnityContainer _container; // 构造函数注入IUnityContainer public MyCustomWindowsService(IUnityContainer container) { _container = container; } protected override void OnStart(string[] args) { // 使用注入的容器注册新类型 _container.RegisterType<INewFeatureService, NewFeatureServiceImpl>(); var featureService = _container.Resolve<INewFeatureService>(); featureService.InitializeFeature(); } }
优缺点:优点是完全遵循依赖注入原则,没有静态耦合,后续单元测试时可以轻松传入模拟容器;缺点是需要调整服务实例的创建方式,比静态方案多几步操作,但长期来看更利于代码维护。
额外注意点
- Unity 2.1的容器注册操作在单线程环境下(比如服务启动的
OnStart方法)是安全的,不用担心并发问题;如果是在后续运行时动态注册,建议加锁保证线程安全。 - 如果你需要创建容器的子容器来隔离注册,可以在服务类里调用
_container.CreateChildContainer(),这样新注册的类型不会影响根容器的配置。
内容的提问来源于stack exchange,提问作者LP13
相关产品推荐
相关产品推荐

