2014-12-23 2 views
1

Я использую Weld SE в приложении, в моем приложении у меня есть интерфейс, для которого у меня есть 3 реализации, но это вызывает неоднозначность для Weld. Насколько я вижу, техника разрешения неоднозначности Weld статична, это можно сделать с помощью: @specialize, @alternative, @Named или с помощью Qualifier. но это мне не помогает. Мне нужно указать конкретную реализацию класса интерфейса для каждого случая.Есть ли способ спросить Weld SE, чтобы ввести конкретную реализацию в данный момент времени?

Я не мог найти решение для моего требования.

Вот код, который иллюстрирует мою точку

public class Foo { 
    @Inject 
    MyInterface target; 
    public void doSomething() { 
     target.doIt(); 
    } 
} 

public class Bar1 implements MyInterface {  
    public void doIt() { 
     System.out.println("Hello"); 
    } 
} 

public class Bar2 implements MyInterface { 
    public void doIt() { 
     System.out.println("Goodbye"); 
    } 

} 


public class FooMain { 
    public static void main(String[] args) { 
     Weld weld = new Weld(); 
     final WeldContainer container = weld.initialize(); 
     Foo foo1 = container.instance().select(Foo.class).get(); 
     Foo foo2 = container.instance().select(Foo.class).get(); 
    } 
} 

Этот код вызывает это исключение:

Exception in thread "main" org.jboss.weld.exceptions.DeploymentException: WELD-001409: Ambiguous dependencies for type MyInterface with qualifiers @Default 
    at injection point [BackedAnnotatedField] @Inject com.lodh.arte.test.cdi.Foo.target 
    at com.lodh.arte.test.cdi.Foo.target(Foo.java:0) 
    Possible dependencies: 
    - Managed Bean [class com.lodh.arte.test.cdi.Bar2] with qualifiers [@Any @Default], 
    - Managed Bean [class com.lodh.arte.test.cdi.Bar1] with qualifiers [@Any @Default] 

мне нужно динамически сказать Weld, реализация которых будет использоваться для инъекций, так же, как в этом мнимом метод Weld.use:

Weld.use (MyInterface.class, Bar1.class); 
Foo foo1 = container.instance().select(Foo.class).get(); 
Weld.use (MyInterface.class, Bar2.class); 
Foo foo2 = container.instance().select(Foo.class).get(); 

Благодарим за помощь

С уважением

Надер

ответ

1

Во-первых у вас есть две реализации MyInterface. Bar1 и Bar2. Weld не знает, какую реализацию выбрать при инъекции MyInterface, поэтому он выбрасывает эту ошибку «Неоднозначные зависимости». Чтобы избежать этой ошибки, вы должны придать вашей реализации разные квалификаторы.

Вы должны квалифицироваться ваши реализации первого:

@MyQualifier1 
public class Bar1 implements MyInterface { 
(...) 
} 

@MyQualifier2 
public class Bar2 implements MyInterface { 
(...) 
} 

Это позволит придать конкретную реализацию, как это:

@Inject 
@MyQualifier1 
MyInterface target; 

Теперь вы нагнетание MyInterface квалифицируется с @MyQualifier1. Во время выполнения его Тип будет Bar1 в этом случае.

Другого подход, если вы хотите, чтобы решить, во время выполнения, реализация которых вам нужно будет использование Instance:

@Inject 
Instance<MyInterface> unqualifiedInstance; 

void do(){ 
    /// first attach the qualifier, we missed at the injection-point: 
    Instance qualifiedInstance = instance.select(new AnnotationLiteral<MyQualifier2>(){}) 
    /// Now you have a qualified Instance, which is a new Object without touching the unqualifiedInstance! 
    MyInterface target = qualifiedInstance.get(); 
    /// so you can decide which implementation you need by passing the qualifier per select-method. in this case its bar2 
    target.doIt(); 
} 

Если вам нужна дополнительная помощь с отборочными вы можете найти документацию сварки и особенно главу 4.3 и следующий полезный. http://docs.jboss.org/weld/reference/latest/en-US/html/injection.html

+0

Благодарим вас за ответ. К сожалению, я не могу изменить код для использования экземпляра. Просматривая так много сайтов на Weld/CDI, я не мог понять, как это сделать. Инъекция, по-видимому, определяется во время загрузки класса. – Nader

+0

Я еще раз прочитал ваш первый пост. Поэтому, если я правильно понимаю ваши потребности, вы хотите сказать, что сварка использует ТОЛЬКО ОДИН из реализаций при инициализации среды сварки. Итак, чтобы сварка теперь использовала только желаемую реализацию для всех инъекций вашего интерфейса? Если нет, не могли бы вы объяснить, что еще вам нужно? –

+0

Извините за задержку. Нет. Мне нужно сообщить Weld в любой момент времени, какую реализацию использовать с текущего времени. Это особенно необходимо для тестов, в которых используется CDI. Для одного теста я хочу, чтобы Bar1 для другого теста мне нужен Bar2. – Nader

Смежные вопросы