3

I'm writing the Windows service Listner for Active MQ. I'm trying to implement Dependency Injection in the project. But i'm not sure where to register Container and how it will be resolved ?

I tried to put it in OnStart method as below, but no luck.

 protected override void OnStart(string[] args)
        {
            container = new WindsorContainer();
            //  IWindsorContainer container = new WindsorContainer();
            //container.Install(FromAssembly.This());
            container.Register(
                Component.For<IHttpClientProxyHandler>().ImplementedBy<HttpClientProxyHandlerWeb>().LifestyleTransient(),
                Component.For<IHttpClientProxy>().ImplementedBy<HttpClientProxyWeb>().LifestyleTransient(),
                //Component.For<IRedisCacheClient>().ImplementedBy<RedisCacheClient>().LifestyleTransient(),
                Component.For<IApplicationSettings>().ImplementedBy<ApplicationSettings>().LifeStyle.PerWebRequest,

                Component.For<ILogger>().ImplementedBy<Logger>().LifeStyle.PerWebRequest

            );


            this.messagingQueue = new ActiveMessagingQueue(new ApplicationSettings(), new Logger());
            this.logger = new Logger();
            this.applicationSettings = new ApplicationSettings();
            this.httpClientProxyHandler = container.Resolve<IHttpClientProxyHandler>();

            this.messagingQueue.OnMessageReceived += this.OnListenerMessage;
        }

Then i tried to put in ServiceBase Constructor- no luck . Even tried putting it in Main function. But im getting below error always in event logger.

'Namespace.HttpClient.HttpClientProxyHandler' is waiting for the following dependencies: - Service 'Castle.Windsor.IWindsorContainer' which was not registered.

Can anyone help here?

PaRsH
  • 1,320
  • 4
  • 28
  • 56
  • 1
    Try using `IKernel` instead of `IWindsorContainer`. And generally you don't want to pass the container/kernel to your implementations... – Patrick Quirk Jul 20 '17 at 18:28

2 Answers2

2

I agree with Patrick that you shouldn't be depending on IWindsorContainer (or IKernel) in your registered components. Instead, depend on the components (or rather, the interfaces those components implement) you need, make sure they're also registered in your container, and let Castle Windsor resolve the whole dependency hierarchy for you.

Why shouldn't you provide a mechanism for resolving dependencies to each component? Well, it hides the actual dependencies of your component and makes mocking/stubbing them in tests more difficult as you have to mock the service locator and the actual dependency. It also pushes responsibility for the management of dependencies on to you; In Castle Windsor if you explicitly Resolve a component it's best practice to also Release it when you're finished. Finally it couples your components to the particular flavour of Dependency Injection you're currently using, I.E. Castle Windsor.

Andy Lamb
  • 2,151
  • 20
  • 22
  • Thanks @Andy Lamb and Patrick. Could you please elaborate bit more. Probably with some example. – PaRsH Jul 21 '17 at 11:50
  • @PaRsH The kernel/container is a type of "service locator", and injecting it is an anti-pattern. Start with [this question/answer](https://stackoverflow.com/q/22795459/1698557), and do some extra Googling if you need more info. – Patrick Quirk Jul 21 '17 at 13:14
0

I would recommend implement it together with Topshelf framework. You can see similar example here:

https://github.com/EasyNetQ/EasyNetQ/wiki/Wiring-up-EasyNetQ-with-TopShelf-and-Windsor

Instead of ActiveMQ they use EasyNetQ, but basically the problem should be the same.

Jan Muncinsky
  • 4,282
  • 4
  • 22
  • 40