Problem with WorkItem reference in Controller

Topics: CAB & Smart Client Software Factory
Apr 1, 2006 at 1:56 PM
originally posted by: sagi44

When initializing my WorkItem, i realized a strange thing.

What is the difference between (Where Presenter inherits from Controller):
Presenter presenter = new Presenter();
and -
Presenter presenter = Items.AddNew<<<Presenter>>>(); ????????
I ask this because when using the first option i get a Null pointer reference to my
WorkItem in the Presenter.
But when using the second option, somehow the parent workitem is ok.
I'd rather use the first method because it allows me to use constructor params.
Has anyone encountered this before?
Apr 8, 2006 at 3:08 AM
originally posted by: turmelma

You can use constructor params even with injection constructors.

First thing you would need to do in your presenter class is to decorate your constructor with params with the InjectionConstructor attribute.

The next condition you need to respect for this to work is that any value that needs to be passed to your constructor must be available in the context of its creation (read: the objects should be in the "Items" collection of the WorkItem hosting this - or be the WorkItem itself)­.

Each parameter would be decorated with the ServiceDependency attribute.

That's how I understand it at this point.
Any remarks on what I just said?
Apr 8, 2006 at 4:44 AM
originally posted by: sagi44

Thanks Marc.
I understand what you're saying and i realized this myself since my post.
Thing is, now that i'm using the guidance package, i've migrated my code away from this approach. Things are still not all that clear to me and i hope they will get clearer.
Apr 13, 2006 at 11:45 AM
originally posted by: ChrisHolmes

Constructor-based injection can still be performed if that's the way you want to handle Dependency Injection.

The reason option #1 returns null is because you are creating the new presenter manually instead of allow the framework to do it with AddNew<>(). If you look at the Controller class you'll find this attribute decorating the WorkItem property:

Dependency(NotPresentBehavior = NotPresentBehavior.ReturnNull)
public WorkItem WorkItem
get { return workItem; }
set { workItem = value; }

Explicitly it is telling it to return null when the WorkItem isn't present during construction of the object. When you create the object manually by doing:

Presenter presenter = new Presenter()

...then there is no WorkItem to be injected, thus the null. To fix this, you need to change your code to this:

Presenter presenter = Items.AddNewPresenter(); // I understand angle brackets are broke on this board, hence the []

As far as Dependency Injection goes you can still use Constructor-based injection. Like suggested you can use the InjectionConstructor attribute to declare a class's Constructor as using DI to perform parameter injection. The CAB documentation, under the section "Design of the Injection Model" describes the various ways to handle DI with constructors and the various attributes you can use to make this happen.

Basically, you decorate the Constructor with the InjectionConstructor attribute. Then, you decorate each constructor parameter with an attribute as well, to tell the DI framework how to provide those arguments. Example:

public MyView(
ServiceDependency WorkItem workItem,
CreateNew MyViewPresenter presenter)
this.presenter = presenter;

There are two different attributes at work here: ServiceDependency and CreateNew.

CreateNew tells the DI framework to create a new MyViewPresenter whenever you create this MyView class and inject it through the constructor. ServiceDependency tells the framework to fetch a reference to the service from the ancestor WorkItem that is creating this MyView and inject that.

If you were to do a MyView view = new MyView() you would see you have to pass a two objects into the constructor:

MyView view = new MyView(workItem, presenter);

Hope some of that helps. If you need more feedback feel free to mail me.
Apr 20, 2006 at 10:59 AM
originally posted by: sagi44

Thanks again Chris for your help.
I will try to stick to object creation vs DI since it is clearer to me
and is more "ole-school".