CAB Dependency Injection

I am currently working on a CAB-based project, and I must tell you I am very disappointed in CAB IoC capabilities. Its IoC functionality is a) limited and b) intermingled with other stuff, violating the single responsibility principle.

Why is CAB IoC limited? Traditional IoC containers work like this: you give the container a string ID of the object you want, the container looks into some configuration and builds the object for you. In CAB you create objects by type, and there is no external configuration – all dependencies must be specified as attributes inside the object type definition. E.g.

Items.AddNew<SomeClass>();

class SomeClass
{
    public SomeClass(
             [Dependency(Name="Input")] MyStream input,
             [Dependency(Name="Output")] MyStream output)
    {
        ...
    }
}

This has several implications:

  • In a particular context, all objects of a particular type will be created in the same way.
  • If you change dependencies, you must recompile the code.
  • You may not be able to supply proper dependencies to the types you don’t control.

Another limitation is that if an object depends on an interface, and the context contains an instance of a class that implements the interface, CAB will not perform the injection. E.g. the following will not work:

interface IView ...;

class View : IView {...}

class Presenter
{
    public Presenter(IView view) { ... }
    ....
}

...
Items.AddNew<View>();
Items.AddNew<Presenter>(); // view will not be found

Note, that CAB does substitute derived classes for base classes, e.g. the following will work:

class ViewBase {...}

class ViewDerived : ViewBase {...}

class Presenter
{
    public Presenter(ViewBase view) { ... }
    ....
}

...
Items.AddNew<ViewDerived>();
Items.AddNew<Presenter>(); // ViewDerived injected instead of ViewBase

But wait – it is getting even funnier. Using out of the box tools you have a choice of:

  • Using Items collection, register your object under its concrete type, possibly with an ID
  • Using Services collection, register your object using an interface type, but without the ID

This means that you must either specify concrete types in your dependent objects, or you may have only one object of each (interface) type.

Leave a Reply

Your email address will not be published. Required fields are marked *