Най-добрият подход за мутиране (добавяне/премахване на свързвания) на Guice инжектор, като същевременно се поддържа състояние

Надявам се да предефинирам или актуализирам някои обвързвания в рамките на модул, който на свой ред се използва от инжектор. Осъзнавам, че модулите са неизменни и след като обвързването бъде засмукано и инжектирано, неговата дефиниция не може да се промени за всички практически цели.

Бих искал да добавя/променя/премахвам обвързвания, като същевременно запазя сингълтоните, които вече живеят в инжектор. Промяната е прост случай, тъй като човек може да постигне този ефект с помощта на доставчик. Въпреки това динамичното добавяне или премахване на ключ (обвързваща дефиниция) е малко по-трудно.

Някакви мисли дали това трябва или може да се направи на практика.

Мисля, че най-добрият начин е да пресъздавам инжектор всеки път, когато се появи обвързване за добавяне/премахване, копиране на дефиниции от оригинала към новия. Всички съществуващи сингълтони ще бъдат предефинирани от toInstance, а не от типа на изпълнение и т.н.


person mP.    schedule 20.06.2010    source източник


Отговори (1)


Детски инжектори могат да се използват за постигане на това, но изисква известна настройка. Детските инжектори ще предотвратят зависимостта на дълготрайните свързвания от краткотрайните. Ето един пример:

class ForeverModule extends AbstractModule {
  ...
}

class TemporaryModule extends AbstractModule {
  ...
}

class Main {
    public static void main(String... args) {
        Injector foreverInjector = Guice.createInjector(new ForeverModule());

        Injector injector = foreverInjector.createChildInjector(
                new TemporaryModule());
        /*
         * Do stuff with the injector as you would normally. When you
         * get bored of that injector, create a replacement injector
         * as a child of the long-lived injector.
         */
    }
}

Обвързванията на Singleton в модула forever ще продължат, докато този модул съществува. Свързванията на Singleton във временния модул ще продължат толкова дълго, колкото използвате съответния инжектор.

Предупреждение: По подразбиране обвързванията точно навреме ще бъдат създадени в инжектора от най-високо ниво. Ако имате нужда обвързването да бъде краткотрайно, трябва да обвържете както интерфейса, така и изпълнението в модула на вашия дъщерен инжектор. Това изглежда така:

public void configure() {
    bind(Foo.class).to(RealFoo.class);
    bind(RealFoo.class);
}
person Jesse Wilson    schedule 20.06.2010
comment
Предполагам, че това би свършило работа, въпреки че човек трябва да планира какво влиза в кой модул, така че нещата да са в отделни модули, като правилният може да се заменя по желание. - person mP.; 20.06.2010
comment
Какви са вашите коментари относно възстановяването на инжектор от нулата чрез копиране върху всички свързвания от оригинала (прескачане на вградените свързвания за c.g.i.Injector.class). Има ли някакви недостатъци с този подход спрямо каскадното и сливащо инжектиране на createChildInjector? - person mP.; 20.06.2010
comment

Освен генерирането на произволни справочни таблици, можете да използвате комбинация от функции:

  • XOR
  • симетрична битова пермутация (например преместване на 16 бита, или обръщане 0-31 на 31-0, или обръщане 0-3 на 3-0, 4-7 на 7-4, ...)
  • Повече ▼?
- person Jesse Wilson; 20.06.2010