开发者

How to inject package private classes using Guice

Firstly i like what Guice does however i have also like to make as few classes in my system public. All services in my system are package private w/ only the interface public. This presents a few problems for Guice if one does not use a provider. I would prefer some alternative that allows me to provide a strategy to do the following:

  1. for component C
  2. requires dependencies X, Y, Z
  3. call this method w/ X, Y, Z to create instance.

.. repeat again for all components.

In step 2 of the above psuedo code Guice now scans for @inject annotations. If this strategy was available I could decide how id like to find my component's dependencies in a generic way.

Unfortunately Module.bind just doesnt work because it works w/ classes literals.

The strategy interface for the above might look like this

interface ComponentDiscoverer {
   Set<ComponentDefinition> components();
}

interface ComponentDefinition<T> {
   List<RequiredDependency> requiredDependencies(); // similar to Guice's Key    
   <T> create( List<SatisfiedDependency> dependencies ); // factory method.
}
  1. Guice gets all components by calling a r开发者_StackOverflow社区egistered ComponentDiscoverer.
  2. It then calls the registered ComponentDiscoverer.components();
  3. For each ComponentDefinition.requiredDependencies()
  4. on demand call ComponentDefinition.create

Is this any built into Guice way or third party library to achieve the above ?

SAMPLE

package companyX;

public interface Service {
   void execute();
}

package companyX;

package private class ServiceImpl implements Service {

   static ServiceImpl create( Dependency dependency){
       return new ServiceImpl( dependency );
   }

   private ServiceImpl( Dependency dependency ){
   }
   void execute();
}

package companyX;

package private class ServiceImpl2 implements Service2{
}

package companyX;

public class Factory {
    Service alpha( Dependency ){
       return ServiceImpl.create( dependency );
    }
    Service beta( DifferentDependency ){
        // boring left out
    }
    Service2 gamma( AnotherDifferentDependency);
}

My module lives in a different package and all creation goes thru Fatory because everything else is package private.


You shouldn't have just one Module unless your application is very simple. You should have a module for each package that you have package-private classes you want to use in. This allows you to bind those package-private classes to the public interfaces. This is a standard practice for using Guice, and it's mentioned in the Keep Constructors Hidden section of the documentation.

With a module in the package, you just need normal @Injectable constructors or provider methods:

@Provides @Alpha Service alpha(Dependency dependency) {
  return ServiceImpl.create(dependency);
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜