2010-09-29 5 views
7

Я создаю библиотеку, которая будет включена как банка, поэтому она не будет содержать основной метод. Мне интересно, что лучше всего подходит для начальной загрузки Guice в этом случае. У меня один синглтон верхнего уровня.Использование Guice без основного метода

public class TestManager 
{ 
    private TestManager() 
    { 
    } 

    public static TestManager getInstance() 
    { 
     // construct and return singleton 
    } 

    public void createSomeObjects() 
    { 
    } 

} 

Куда я должен загружать Guice? Я думал, что в конструкторе я могу назвать Guice.createInjector (новый модуль()); но он не будет вводить ни один из объектов, созданных в createSomeObjects().

Есть ли общий способ сделать это, когда у вас нет основного метода()?

Cheers.

ответ

8

Подобно конфигурации лесозаготовок, если это настоящая библиотека, то ваши варианты в значительной степени это:

  • Сообщите пользователю библиотеки, что они несут ответственность за самих самонастройки Guice.
  • Обеспечить метод инициализации библиотеки, которая заботится о самонастройке Guice, если они хотят использовать библиотеку

Попытку сделать библиотеку супер-умным, чтобы сделать самоконфигурацию часто заканчивается несколько негибких, жестким для проверки иерархии классов.

+5

Предоставление клиентам модуля Guice может работать хорошо. –

+1

+1 для супер-умной самоконфигурации. Просто подумайте о том, как плохо это произошло с регистрацией Apache Commons. –

+0

@ Джесси, я никогда не видел библиотеки, которые используют Guice, на самом деле выставляют ее конечным пользователям. Например, Maven и JIRA используют IoC за кулисами, но они вводят в ваши классы, не зная, какую реализацию они используют. Появление Guice звучит чище (если пользователь удобен с Guice), но я боюсь, что это может напугать пользователей (почему еще никто этого не делает?). – Gili

0

Это не то, что вы должны делать, но то, что вы могли бы сделать:

Пусть ключевые классы в вашей библиотеке расширить или иным образом ссылаться на класс, который инициализирует все в статическом блоке. Это очень грязный хак, но если вы убедитесь, что ваш api не может быть доступен без загрузки загрузчика класса инициализатора, вы должны быть в безопасности.

Вы можете сделать его немного более чистым, если вы использовали AspectJ и ввели частного члена типа инициализатора во все классы в вашей библиотеке (без касания java-кода), но это все равно было бы взломом.

0

Если вы используете Guice в области вашей библиотеки, а не для всего приложения, вы можете использовать статический блок в классе TestManager.

В этой стратегии предполагается, что приложение в какой-то момент вызовет TestManager.getInstance() и что это единственная точка входа в ваш API.

@Singleton 
class TestManager { 

    private static final TestManager INSTANCE; 

    static { 
    INSTANCE = Guice.createInjector(new Module()).getInstance(TestManager.class); 
    } 

    private TestManager() { 
    } 

    public static TestManager getInstance() { 
     return INSTANCE; 
    } 

    @Inject 
    public void createSomeObjects(YourDependencies ...) { 
    // Do something with dependencies 
    } 
} 
Смежные вопросы