views:

35

answers:

1

Hello,

I'm facing some architectural problems on the project I'm involved in. The project is an ASP.NET MVC 2 application that relies on DI and especially on constructor injection with Unity. The application is divided into several modules (each module is a set of assembies) that exposes services to other modules. Those services are registered to Unity at application startup. Nothing special untill now. Let's say I have this (each module is an assembly for simplification) :

ModuleA, ModuleB.

ModuleA exposes a service 'IServiceA' with the following methods :

IServiceA (Operation1 - Operation2 - Operation3)

ServiceB from ModuleB needs IServiceA from ModuleA and it gets it by the constructor injection (with concrete implementation). Then it uses it.

The problem is when ModuleA is desactivated (we check in the database if the module is acivated for the current user at application startup) so the serviceA is not registered with Unity.

Then we have an exception at runtime because unity can't find a registration for a IServiceA and ServiceB cannot be constructed. Which is normal.

I would like to know it there is a set of patterns or the best practice to deal with it. My first though was to get rid of constructor injection for ServiceB. But then I should use the hard reference to the ServiceA and I don't like it or to use a ServiceLocator which is even worse. I don't want to check in ModuleB if ServiceA is available or not, because there will be many other services I would check and should deal with a code thats pure infrastructural. I would like that ServiceB runs the same code if the serviceA is available or not (don't know if possible). I looked at a Gateway pattern but don't know if this can help me.

Any help will be appreciated.

Thanks,

+2  A: 

You'll need some sort of default implementation that can take over when ModuleA is deactivated. The Null Object pattern sounds like a perfect fit.

Just register your NullServiceA with Unity first. This will be the default IServiceA unless overwritten by the real implementation (let's call it ConcreteServiceA).

For a more sophisticated implementation, you can wrap NullServiceA and ConcreteServiceA in a Composite, or perhaps another form of Decorator that chooses one over the other based upon availability.

You could, for example, have a Composite that always uses the first (or the last) of the IServiceA instances injected into it... or perhaps the selection criterion could be based upon some sort of metadata that determines whether the module is activated or deactivated (sounds like that information itself could fit well into a hypothetical IModule interface).

Mark Seemann
Thanks for your response. Unfortunatelly there is no a default implementation. In the very first spirit of the application each module should 'add' new fonctionnality but other modules should live without if not available. Now all modules are connected and one module calls another all the time. I though about implementing a null object but don't know if it will fit very well for some reasons. How to deal with the Dto that Operation1, Operation2 and Operation3 return ? The Dto should be fake ?What if Operation4 return a boolean ? Should I deal with it like the real service returned that value ?
Thomas Jaskula
Whenever you define an interface, think good and hard about what a Null Object implementation will look like. If you can't come up with a good hypothetical implementation, it's a design smell. See if you can't pull the design more towards the Hollywood Principle. Methods that return void can always have a null implementation.
Mark Seemann
Thanks, something like passing around a context to the method and change it's implementation to null ?
Thomas Jaskula
Yes, e.g. instead of passing in primitive parameters and expecting primitive values out, you can often change a method signature to accept some sort of Command object or another complex type, and change the return type to void. Then a Null Object implementations can simply ignore the input.
Mark Seemann