You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cloudstack.apache.org by Darren Shepherd <da...@gmail.com> on 2013/08/28 20:55:36 UTC

ComponentContext.inject() usage in storage framework

The new storage framework uses ComponentContext.inject() extensively. 
Why is that?  ComponentContext.inject() should really never be used.  It 
breaks IoC and DI patterns.

For example, in configure() of SwiftImageStoreProviderImpl it does

lifeCycle = ComponentContext.inject(SwiftImageStoreLifeCycleImpl.class);
driver = ComponentContext.inject(SwiftImageStoreDriverImpl.class);

Why not just do the below? It keeps the IoC/DI pattern and should do the 
same thing.

@Inject
SwiftImageStoreLifeCycleImpl lifeCycle;
@Inject
SwiftImageStoreDriverImpl driver;


Darren

Re: ComponentContext.inject() usage in storage framework

Posted by Darren Shepherd <da...@gmail.com>.
On 08/28/2013 01:41 PM, Edison Su wrote:
> There are cases, the object is not singleton, such as VolumeObject, but it needs to access DAO, then either we need to pass the DAOs in the VolumeObject's constructor, or through ComponentContext.inject(), or using AspectJ's @Configurable(http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/aop.html#aop-atconfigurable)
> BTW, why  ComponentContext.inject() breaks IoC and DI patterns? Per my understanding, ComponentContext.inject() just tells IoC container to take care of the object creation, as the object created by "new" operator won't be injected by IoC container by default.
>

By calling inject() your basically inverting the inversion of control. 
So, in short, what your doing is using Spring as a gloried factory or 
service locator.  If that is the case, then just use that pattern as its 
more explicit.

With VolumeObject it appears that you have create a framework managed 
object.  So you really should just have a factory or actually a 
repository (being that your looking it up).  So have a 
StorageObjectRepository or something like that, that has a 
StorageObjectRepository.getVolume().  The repository object can have the 
DAO's injected to it and then in the getVolume() call you need to 
contstruct the impl object and set the DAOs (in the constructor 
probably) on the impl object.

Now inject() specifically causes a larger problem for what I want to do. 
  I'm working on the idea of putting in a true module system into 
cloudstack (ugly pictures and some words at 
https://cwiki.apache.org/confluence/display/CLOUDSTACK/Nothing+to+see+here...#Nothingtoseehere...-ModuleSystem) 
and inject() will break it.

The problem with inject() is that is assumes there is a single global 
application context.  In a hierarchy, like I'm going to propose 
eventually, no single global application context can exist if you have a 
tree with siblings.

Darren


RE: ComponentContext.inject() usage in storage framework

Posted by Edison Su <Ed...@citrix.com>.
There are cases, the object is not singleton, such as VolumeObject, but it needs to access DAO, then either we need to pass the DAOs in the VolumeObject's constructor, or through ComponentContext.inject(), or using AspectJ's @Configurable(http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/aop.html#aop-atconfigurable)
BTW, why  ComponentContext.inject() breaks IoC and DI patterns? Per my understanding, ComponentContext.inject() just tells IoC container to take care of the object creation, as the object created by "new" operator won't be injected by IoC container by default.

> -----Original Message-----
> From: Darren Shepherd [mailto:darren.s.shepherd@gmail.com]
> Sent: Wednesday, August 28, 2013 11:56 AM
> To: dev@cloudstack.apache.org
> Subject: ComponentContext.inject() usage in storage framework
> 
> The new storage framework uses ComponentContext.inject() extensively.
> Why is that?  ComponentContext.inject() should really never be used.  It
> breaks IoC and DI patterns.
> 
> For example, in configure() of SwiftImageStoreProviderImpl it does
> 
> lifeCycle = ComponentContext.inject(SwiftImageStoreLifeCycleImpl.class);
> driver = ComponentContext.inject(SwiftImageStoreDriverImpl.class);
> 
> Why not just do the below? It keeps the IoC/DI pattern and should do the
> same thing.
> 
> @Inject
> SwiftImageStoreLifeCycleImpl lifeCycle;
> @Inject
> SwiftImageStoreDriverImpl driver;
> 
> 
> Darren