2011-09-06 2 views
0

У меня есть класс с параметризованным конструктор, используя AssistedInject следующим образом:Guice помощь инъекции

@Inject 
    Portfolio (QuoteDao dao, @Assisted Params params) {...} 

создать экземпляр этого класса в команде обработки сервлетов:

public class Handler { 
    @Inject Strategy strategy; 
    Result execute(Action action) { 
     Portfolio portfolio = portfolioFactory.create(action.params); 
     strategy.execute(); 
    } 
    } 

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

public class Strategy { 
    Portfolio portfolio; <-- how should I get this here? 
    @Inject 
    public Strategy(QuoteDao dao, ??) {...} 
    public execute(); 
    } 

пример несколько упрощается - это не возможно просто передать портфель как часть вызова Execute().

Я думал, что с помощью различных решений, но ни один не кажется, идеально:

  • Подайте PortfolioProvider - но как провайдер получить доступ к портфелю?
  • Сохранить портфель в обработчике от зарегистрированного пользователя (я использую AppEngine), затем с помощью зарегистрированного пользователя, чтобы получить в поставщика - но я хотел бы систему, чтобы иметь возможность обрабатывать анонимные пользователей
  • Храните портфель в статическом ThreadLocal, доступ в провайдера снова - кажется очень неуклюжим

Оценил это очень много, если кто-то может помочь мне здесь? Я новичок с Guice, так что надеюсь, я что-то очевидное ...

Спасибо, Марк

ответ

0

ThreadLocal фактически может быть вашим лучшим выбором не хватает. Взгляните на SimpleScope, который использует ThreadLocals, чтобы сделать значение, которое можно вводить для тела блока кода. Если вы уже используете интеграцию сервлетов Guice, вам нужно написать ServletFilter для входа и выхода из SimpleScope.

+0

Спасибо за ответ Джесси - после долгих размышлений в конце я решил ввести RequestScoped PortfolioProvider и вызвать setter, чтобы инициализировать его в обработчике команд. Затем я могу приложить поставщика в другом месте приложения и получить доступ к портфолио. Я предполагаю, что область запроса использует threadlocal под обложками так или иначе? – MarkNS

0

Возможно ли, чтобы параметр Portfolio был параметром для других методов, которые в нем нуждаются? Например, вместо portfolio, являющегося частным членом класса Strategy, должен ли он быть параметром execute? Это зависит от того, сколько разных мест вам нужно.

public class Strategy { 
    @Inject 
    public Strategy(QuoteDao dao, ??) {...} 
    public execute(Portfolio portfolio); 
} 

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

+0

Привет, МакКамей, спасибо за ответ, но причина, по которой я не хочу этого делать, - это то, что портфолио нужно вводить в несколько разных компонентов приложения. Безопасность потоков не вызывает беспокойства, поскольку (хотя сервлет является одиночным) запрос выполняется в requestcope. – MarkNS

+0

Я подумал, что это, вероятно, дело, но стоит того, чтобы он был подходящим. Удачи. – mckamey

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