Unity DI on a Windows service, maybe?

I am developing a Windows service to perform periodic operations, can I use Unity to input my classes from another library?

I want to use the [Dependency] attribute for my services, registering components at the Windows service entry point.

Example:

static class Program { static void Main() { ServiceBase[] ServicesToRun; UnityConfig.RegisterComponents(); ServicesToRun = new ServiceBase[] { new EventChecker() }; ServiceBase.Run(ServicesToRun); } } public static class UnityConfig { public static void RegisterComponents() { UnityContainer container = new UnityContainer(); container.RegisterType<IEventBL, EventBL>(); } } public partial class EventChecker : ServiceBase { private Logger LOG = LogManager.GetCurrentClassLogger(); [Dependency] public Lazy<IEventBL> EventBL { get; set; } protected override void OnStart(string[] args) { var events = EventBL.Value.PendingExecution(1); } } 

In this case, EventBL is always null, so [Dependency] on one is not allowed. There is no way to make it work?

Thanks!


Solution found:

After writing the answer, I found a possible solution that calls the container creation method for creating the service class:

  UnityContainer container = new UnityContainer(); UnityConfig.RegisterComponents(container); ServiceBase[] ServicesToRun; ServicesToRun = new ServiceBase[] { container.BuildUp(new EventChecker()) }; ServiceBase.Run(ServicesToRun); 

If you know any other solution, share it :)

+8
c # dependency-injection unity-container windows-services
source share
1 answer

Of course, you can use the DI library to help you in Windows Services. Please note that in general you should use design injection. This prevents a temporary link and prevents your code from depending on the DI library itself (which is pretty ironic because it needs a dependency on the DI library because it is trying to help you prevent a strong link between the components).

In addition, you should simply allow the container to allow its services. In other words, do not update your services manually, but request a new instance from the container:

 ServicesToRun = new ServiceBase[] { container.Resolve<EventChecker>() }; 

But please note that your EventChecker allowed once and remains for the entire duration of the application. This effectively makes it singleton and at the same time all its dependencies will become single. So instead, it's best to make your part of the ServiceBase implementation part of the composition root and allow new instances from the container every time your time fires:

 public class EventChecker : ServiceBase { private static IUnityContainer container; public EventChecker(IUnityContainer container) { this.container = container; } public void SomeOperationThatGetsTriggeredByATimer() { using (this.container.StartSomeScope()) { var service = this.container.Resolve<IEventCheckerService>(); service.Process(); } } } 
+14
source share

All Articles