My question has to do with the WCF and typed factory facilities that is provided by Windsor. I am quite new to the IoC container concepts and especially facilities but started looking into it after evaluating a project we wrote a while back. The program is n-layered and not very unit testable because dependency injection is not implemented everywhere. The issue is that since it is n-layered, to do a proper DI would end up making the top layer responsible for creating an instance of something that will get used like 5 layers down; so I turned to IoC.
However, after reading many a SO article and other sites I am now stuck with a couple of issues. One of the main issues initially was to decouple a class from a physical implementation of a WCF service and I did it as follows:
service = ManagerService.IoC.Resolve<IGridSubmitWorkService>(new { binding = new BasicHttpBinding(), remoteAddress = new EndpointAddress(WorkerAddress) });
result = service.SubmitWorkUnit(out errorString, aWorkUnit);
ManagerService.IoC.Release(service);
However, I found multiple mentions as to how you should not be using IoC.Resolve<>()
and should rather use factories and WCF facilities to remove the dependency on your IoC container
and that it is a service locator pattern which some people consider to be an anti-pattern.
My issue is this: The above three lines of code solves almost all my problems but to follow the proper patterns I have to instead create a WCF facility, a typed factory (that will deal with providing me instances of the class where this code is used) and a new interface for the factory and this feels like over-engineering and adding unnecessary complication to the code just for the sake of pleasing a pattern.
Question 1: Is there something fundamental I am missing here?
Question 2: As you can see from the code, I am calling a non-empty constructor for the web service. Will this still be as simple if I implement a WCF facility?
Question 3: Can you point me to a decent tutorial on using WCF facilities since I found the explanations on the Windsor wiki to be very brief and not really useful?
Thanks
Q1. Yes I think there is something important being missed. In your three line example, all you have done is replaced one implementation dependency (your GridSubmitWorkService) with another one (ManagerService.IoC). To illustrate, why not make it even simpler with the following?
service = new GridSubmitWorkService(binding,remoteAddress);
result = service.SubmitWorkUnit();
This is even simpler again but it has the hardwired implementation dependency. The point is that constructor and property injection allow you to write clean components that do not have to understand how the plumbing is done. In both your code and my code that principle is violated - the components are managing their own plumbing and in a large application, that becomes very painful, very quickly. This is why ServiceLocator is considered by many to be an anti-pattern.
The name of your service locator itself gives the game away. It's called IoC - abbreviation for Inversion of Control. But when you look at the structure of these two bits of code you can clearly see that nothing has been inverted - the code is doing pretty much the same thing in both cases, but your example is just a little more abstract and convoluted.
Also no-one offering IoC is trying to force you to stick to a pattern. If you don't see the benefit or the benefits simply aren't there for your app, then please don't use the pattern.
Q2. Any decent DI container is based on constructor injection. Using the Windsor WCF facility is very straight-forward and it supports a variety of hosting methods so things like bindings and addresses are handled properly anyway.
Q3. There is plenty of information around ranging from forums to questions here on stackoverflow.com, in addition to the Windsor docs and wikis. I suggest putting a specific question if there is something you are unable to resolve.