Adding a CAB Service to a module WorkItem

Topics: CAB & Smart Client Software Factory
Nov 8, 2007 at 10:02 PM
Our application compriss a bunch of modules. In one of these modules, I have an Interface implementation decorated with
Service(typeof(IIOConfigServices)). Interface name is IIOConfigServices.

What I am attempting to do is add and instance of IOConfigServices to the Services collection of my module's WorkItem instead of the root WorkItem of the application. Also, I want to be able to inject the module's WorkItem into this service.

I am having trouble understanding what Service(typeof(IIOConfigServices)) actually does, whether it is tagging interface implementation IOConfigServices to be added to the root WorkItem, or to the module's WorkItem.

Desperately, I have also added the following statement in the OnBuiltUp method of my module's WorkItem:

this.Services.AddNew<IOConfigServices>();

in order to add this Service to the module's Service collection. Seems to me that I either decorate the IOConfigServices class with

Service(typeof(IIOConfigServices))]

or manually add an instance of this class into the module's WorkItem using

this.Services.AddNew<IOConfigServices, IIOConfigServices>().

Which of these methods is correct? If neither, can someone please clarify how to add my service into a module's WorkItem and not the parent's WorkItem service collection?

Also, after adding the Service into the module's WorkItem collection, is it possible to access the hosting WorkItem from the service?

TIA.



Nov 9, 2007 at 12:02 AM

Which of these methods is correct? If neither, can someone please clarify how to add my service into a module's WorkItem and not the parent's WorkItem service collection?



Either is probably correct (I say probably because I only use the second method).

What we did is create a ModuleControllerBase class, that our root level Module WorkItems inherit from. The ModuleControllerBase class inherits from WorkItem, but it has several virtual methods like AddServices() which make it easier for developers when creating new Modules to figure out where to put code.

In AddServices, I would do the second:

Services.AddNew<IOConfigService, IIOConfigService>();



Also, after adding the Service into the module's WorkItem collection, is it possible to access the hosting WorkItem from the service?


If you inject it into the Service via Dependency Injection:

 [ServiceDependency]
        public WorkItem WorkItem
        {
            get { return _workItem; }
            set { _workItem = value; }
        }
 

Something like that should work. Hope it helps.

-Chris
Nov 10, 2007 at 2:43 AM

In AddServices, I would do the second:

Services.AddNew<IOConfigService, IIOConfigService>();



In the ModuleInit class of the module whose only WorkItem is called IOConfigWorkItem, I am doing the following:

     //Add our custom IIOConfigService
        public override void AddServices()
        {
            base.AddServices();
 
            // Create instance of IOConfigWorkItem and add
            // our custom service to its collection.
            IOConfigWorkitem ioConfigWorkItem = new IOConfigWorkitem();
            
            ioConfigWorkItem.Services.AddNew<IOConfigServices, IIOConfigServices>();                            
        }

Recall that I want and instance of IOConfigServices added only to the service collection of IOConfigWorkItem, and not the root WorkItem.

Yet, an exception is being thrown that says "object reference not set to instance of object." This is being thrown by the ModuleLoaderService, being unable to instantiate IOConfigWorkItem . Is there a strict order which must be followed to add a service to a non-root WorkItem? In order words, does the module have to be loaded before its WorkItem can be instantiated?

Thanks again.
Nov 10, 2007 at 4:29 AM

Is there a strict order which must be followed to add a service to a non-root WorkItem? In order words, does the module have to be loaded before its WorkItem can be instantiated?

Thanks again.


The problem, I think, is that you have created the WorkItem, but not through ObjectBuilder. You've done this:

IOConfigWorkitem ioConfigWorkItem = new IOConfigWorkitem();

Which creates the WorkItem, but only the WorkItem. So it hasn't been BuiltUp by ObjectBuilder, it has no dependencies injected, and it hasn't been added to the hierarchy of WorkItems.

I think you need to do this instead (In ModuleInit):

IOConfigWorkItem workItem = WorkItems.AddNew<IOConfigWorkItem>();

And then in the IOConfigWorkItem itself:

public override void OnRunStarted()
{
    Services.Addnew<IOConfigServices, IIOConfigServices>();
}


If you ever want to add a Service to a WorkItem and only that WorkItem (and it's children, obviously) then you can do that in the WorkItem, after it's created. Then some external WorkItem or ModuleController never has to deal with it or know about it.
Nov 11, 2007 at 5:56 AM
The devil is in the details.

Thanks alot for the help.