2011-01-25 4 views
26

Мне нужно связать один класс как реализацию двух интерфейсов. И он должен быть привязан в одноэлементном пространстве.Как связать одну реализацию с несколькими интерфейсами с Google Guice?

Что я сделал:

bind(FirstSettings.class). 
    to(DefaultSettings.class). 
    in(Singleton.class); 
bind(SecondSettings.class). 
    to(DefaultSettings.class). 
    in(Singleton.class); 

Но, очевидно, это приводит к созданию двух различных экземпляров, потому что они переплетены с разными ключами.

Мой вопрос: как я могу это сделать?

ответ

50

Guice's wiki имеет a documentation about this use case.

В принципе, это то, что вы должны сделать:

// Declare that the provider of DefaultSettings is a singleton 
bind(DefaultSettings.class).in(Singleton.class); 

// Bind the providers of the interfaces FirstSettings and SecondSettings 
// to the provider of DefaultSettings (which is a singleton as defined above) 
bind(FirstSettings.class).to(DefaultSettings.class); 
bind(SecondSettings.class).to(DefaultSettings.class); 

Там нет необходимости указывать какие-либо дополнительные классы: просто думаю, что с точки зрения Provider с и ответ приходит довольно естественно.

+1

Самое элегантное решение! –

2

Так, DefaultSettings является реализация как в FirstSettings и SecondSettings, а именно:

public class DefaultSettings implements FirstSettings, SecondSettings 
{ 
} 

Допустим, у вас есть класс EngineA и EngineB

public class EngineA 
{ 
    @Inject 
    private FirstSettings settings; 
} 

public class EngineB 
{ 
    @Inject 
    private SecondSettings settings; 
} 

и вы хотели бы, чтобы ввести такой же реализация.

Вы можете объявить интерфейс DefaultSettingsInterface

public interface DefaultSettingsInterface extends FirstSettings, SecondSettings 
{ 
} 

и сделать DefaultSettings реализовать DefaultSettingsInterface

public class DefaultSettings implements DefaultSettingsInterface 
{ 
} 

Тогда конфигурация может быть:

bind(FirstSettings.class).to(DefaultSettingsInterface.class); 
bind(SecondSettings.class).to(DefaultSettingInterface.class); 
bind(DefaultSettingsInterface.class).to(DefaultSettings.class).in(Singleton.class); 
+1

Спасибо, Борис! Я считаю, что ваше решение работает! Я только что нашел другой способ: bind (FirstSettings.class). - (DefaultSettings.class). in (Singleton.class); bind (SecondSettings.class). - (FirstSettings.class). in (Singleton.class); Кажется, он работает тоже. Как вы думаете? – Pavel

+1

Я не знал, что FirstSettings расширяет SecondSettings. В этом случае он действителен и намного короче. Отправьте свое решение в качестве ответа и через некоторое время продвиньте его как лучший :) –

+0

Да, это правда. Моя вина, я не упоминал об этом :) – Pavel

3

решение, я нашел есть:

bind(FirstSettings.class). 
    to(DefaultSettings.class). 
    in(Singleton.class); 
bind(SecondSettings.class). 
    to(FirstSettings.class). 
    in(Singleton.class); 

Это работает в моем случае, потому что SecondSettings расширяет FirstSettings.

+1

Работает только в том случае, если SecondSettings - это подкласс Subinterface FirstSettings. Существуют решения для этого случая и другие, где нет связи между FirstSettings и SecondSettings. –