[Design] ObjectBuilder Attribute dependencies

Topics: CAB & Smart Client Software Factory
Oct 25, 2005 at 9:33 PM
originally posted by: obiwan

As far as I can tell, the ObjectBuilder attributes guides the injection of dependencies. This means that the object created must have these attributes set to make use of all the neat DI options. But this introduces a dependency that is unwanted in my view. This would breed classes that are "only" creatable with the objectbuilder and when used in another context would drag the ObjectBuilder assembly dependency around with them. Why was this not solved in config? Would the config become too complex?

Any thoughts or insight would be most welcome.

Grtx,
Marc "Obiwan" Jacobi
Oct 26, 2005 at 3:27 AM
originally posted by: BradWilsonMSFT

Not necessarily.

Let's take, for example, a class that requires a service to do its work. We write this class with a constructor like:

InjectionConstructor
public MyClass(ServiceDependency ISomeService svc) { ... }

That clearly expresses the requirements of the class. Even though those things are decorated with DI "guidance", that doesn't mean you can't directly create that class and pass it an instance of ISomeService. In fact, from the outside user's point of view, they aren't even aware that these attributes exist; they merely see this as your constructor, indicating your requirements.

For this reason, we highly prefer constructor injection. It lets you write plain-old .NET objects, which express their requirements in constructors where users expect them to be, with just a little bit of guidance about how they should be handled in a dependency injected world. Property setter injection, on the other hand, means that the issue of getting a fully created and configured object becomes a task of documentation, because you would need to tell users of such objects: "After creating the object, don't forget to set property A, property B, property Q...".

Thoughts?
Oct 30, 2005 at 4:23 PM
originally posted by: jwmc

As a side note, if the ISomeService svc parameter's implementation class is set to AddOnDemand=true, it will NOT be created before injection and cause an exception.
Oct 30, 2005 at 11:02 PM
originally posted by: obiwan

I agree that passing the (service) dependencies in the constructor is more "natural" than setter injection. But still the attributes needed for DI "guidance" introduce a dependency to your framework, while not adding anything to the "expression of requirements" of that class. Maybe if you would split up the ObjectBuilder assembly in a "fx" and a "interfaces" part (if that would be possible). The size of the dependent assembly -that has no further dependencies- the MyClass class drags along is at least small and to the point (it contains stuff to interface with the fx, such as attributes) although it wouldn't be used if the MyClass class was created in/by a different framework/application.

If there would be a generic set of DI attributes (in a System.Xxxx namespace) that any DI implementation could read and use for its "guidence", the problem wouldn't exist. The dependency would be part of the .NET fx and therefor present on the machine running the DI code.

I know I'm splitting hairs here, but in my view dependencies are very important to keep in check. The point is that I think a DI framework should not impose upon the object it creates to follow certain rules. Those rules should be described elsewhere and than mapped as some sort of policy at runtime. Whats the point of making reusable services if they carry "garbage" from some kind of Fx. What if I have several of those frameworks deployed through my enterprise. Should I decorate all my classes with all flavors of (attributes of) DI fx's?

It's like the (1.x) EntLib dll's included testcode. That made you have to deploy the Nunit.dll on your production environment. Is it just me, or.... ;-)