On Apr 3, 12:15 am, Michael Hart <
michael.hart...@gmail.com> wrote:
> My point was that you seem to be overusing the Service Locator pattern
> - not actually declaring your dependencies at all.
>
> Or even better, use a DB factory that returns a connection given a
> connection string name and get rid of the ConnectionStringManager
> altogether.
I use the System.Data.DbProviderFactory. And our systems must be able
to connect with any database.
So even when the DB factory was able to set the connectionstring I
wasn't able to use it.
I try to pass as little objects using the constructor. Mostly I use
property injection. And here lies a problem if you're using Unity. It
requires that you set the InjectionProperty attribute.
So I had to write all kind of object builders to inject the stuff at
both ObjectBuilder and Unity level. Unlike with Ninject you can't
change the attributes it looks for.
Lucky for me, Unity isn't widely in use with corporations. At least in
Europe (financial sector) Windsor Containers and Spring.net as the
most popular DI frameworks, but Ninject is gaining ground fast.
> My point is, instead of littering your code with static references to
> some service locator - or even passing the service locator around -
> just declare your dependencies explicitly. It will make your code much
> easier to test and makes the intent much clearer to anyone reading it.
> Then using Ninject, or whatever IoC container you choose, setup your
> objects from the root so that dependencies can be passed down.
As I mentioned earlier, we mostly provide services. Some services
exists in classes, others are just a static methods. Our main audience
are intermediaries up to 50 employees with little or no development
experience.
Key is to hide as much as possible. The core framework is using real
dependency injection. Although we have written an implementation for
Microsoft CSL, it still requires the developer to setup the container
instance.
As Microsoft CSL is mostly a frontend facade to DI frameworks it
doesn't take care of the bindings itself. Our IocFactory does register
the bindings with the container and even has support for dependencies.
Every ServiceRegistration can specify on which dependencies it counts.
These dependencies are also used to determine the load order as a
service might have Initialization request. The Initialization method
is called the moment the binding is registered with the container.
I can't say the 'bridging' class unit tests are harder to write than
unit tests for class that follow 'proper' DI conventions. But I have
to agree that code with less service locator code is cleaner. However
if only one method is using a certain service, I will not use property
injection, but use the service locator or you end up with classes with
so much fields and properties to hold references that it becomes
harder to 'see' what properties are controlling class behavior and
which are only for infrastructure and you use more memory than needed
as the GC can only dispose the reference variables when the class
itself is disposed. When you only use a service in one method, in our
case it's better to use a service locator and store a reference in a
local variable. This variable is disposed (or at least marked for
disposal) the moment the method is finished. Some services are also
running on third party servers and no-one's waiting for resource hogs.
But I feel we drifting to much to my usage of DI framework which isn't
how most developers would use Ninject.
At the beginning of this thread (some light years ago ;-) someone made
the remark that singletons make unit testing harder and that
singletons needs to be global. I responded that that remark. But
whether you use a service locator to retrieve a service or use some
kind of injection doesn't really matter. I was trying to make that
point.
With regards,
Dave