2014-07-01 70 views
0

我正在使用Google Guice IoC容器。我有两个包,一个包含接口,另一个包含这些接口的实现。Google Guice绑定问题

的ClassFinder类从一个包返回类的列表。

当我尝试绑定接口来实现,我收到以下编译错误:无法从方法解决方法<java.lang.Class<capture<?>>

该API指定到可以采取作为一个参数类和packageClass是1类。应该是什么问题?

public void autoMatch(String basePackageName) 
    { 
     String interfacesPackage = basePackageName + "." + interfacesPackageName; 
     String implementationPackage = basePackageName + "." + implementationPackageName; 

     List<Class<?>> interfaces = ClassFinder.find(interfacesPackage); 
     List<Class<?>> implementations = ClassFinder.find(implementationPackage); 
     for(Class<?> packageClass : implementations) 
     { 
      String name = packageClass.getSimpleName(); 
      try 
      { 
       Class<?> foundInterface 
         = interfaces.stream() 
          .filter(packageInterface -> packageInterface.getSimpleName().equals(name + "Interface")) 
          .findFirst().get(); 
       bind(foundInterface).to(packageClass); 
      } 
      catch (NoSuchElementException exception) 
      { 
       Log.error("IoC", "Could not match interface to implementation", exception); 
      } 
     } 
    } 

编辑

管理通过强制转换(类)来解决这个问题。找到该类,但绑定时抛出java.lang.NullPointerException。

+0

你为什么这样做? –

+0

当我在一个包中有很多类并且场景是1个接口/ 1个实现时,这是一种创建绑定的简单方法。如果有特殊情况发生,它将被区别对待。你会用什么方法? @ThorbjørnRavnAndersen – IsKernel

+0

有多少?从Guice切换到匕首后,我不得不重新审视自己的习惯。 –

回答

1

的问题是,你在编译时类实现接口松动的信息。从编译器的角度来看,最终会得到两个不相关的Class<?>对象,而Guice是用泛型编写的,因此没有办法将它们彼此绑定。

未经测试:考虑使用Class而不是Class<?>,因此不使用泛型。

这就是说,我会建议你手工编写20-30绑定了。依赖注入的想法是将接口从其实现中分离出来,并且你的方法会引入微妙的,很难调试它们之间的运行时依赖关系,我认为这不是件好事。

0

通过不再使用ClassFinder找到类和利用的思考图书馆固定的问题。

public void autoMatch(String basePackageName) 
{ 
    String interfacesPackage = basePackageName + "." + interfacesPackageName; 
    String implementationPackage = basePackageName + "." + implementationPackageName; 

    Reflections interfacesReflections = new Reflections(interfacesPackage); 
    Reflections implementationsReflections = new Reflections(implementationPackage); 

    Set<Class<? extends Object>> interfaces = interfacesReflections.getSubTypesOf(Object.class); 
    Set<Class<? extends Object>> implementations = implementationsReflections.getSubTypesOf(Object.class); 

    for(Class<?> packageClass : implementations) 
    { 
     String name = packageClass.getSimpleName(); 
     try 
     { 
      Class<?> foundInterface 
        = interfaces.stream() 
         .filter(packageInterface -> packageInterface.getSimpleName().equals(name + "Interface")) 
         .findFirst().get(); 
      bind(foundInterface).to((Class)packageClass); 
     } 
     catch (NoSuchElementException exception) 
     { 
      Log.error("IoC", "Could not match interface to implementation", exception); 
     } 
    } 
}