Когда вы регистрируете свою основную форму с помощью контейнера DI, вы можете указать фабричную функцию для создания экземпляра, передав его методу DelegateTo
.
На мой взгляд, нет необходимости разрешать основную форму как интерфейс, потому что это корень композиции, и он не будет передаваться нигде, поэтому я зарегистрирую его, как показано ниже.
container.RegisterType<TMainForm,TMainForm>.DelegateTo(
function: TMainForm
begin
Application.CreateForm(TMainForm, Result);
end);
И тогда вы можете просто разрешить это вызывая
container.Resolve<TMainForm>;
Однако преимущество позволяя контейнер решить форму, что она может придать зависимостей в него, не будет здесь с кодом внутри CreateForm
создает экземпляр. Вот в чем заключается возможность вызова дополнительных методов через контейнер после строительства. Таким образом, вместо того, чтобы передавать зависимость в конструктор, как обычно, вы можете добавить метод let: Init
к классу форм, который принимает необходимые ему зависимости и добавляет к нему атрибут [Inject]
. Это укажет контейнеру вызов этого метода после создания экземпляра (в нашем случае через функцию фабрики, переданного методу DelegateTo) и передать все необходимые ему зависимости.
Минимальная пустая основная форма, которая может принимать зависимости с помощью контейнера будет выглядеть следующим образом:
TMainForm = class(TForm)
public
[Inject]
procedure Init(...);
end;
В конце концов что-то должно назвать 'Application.CreateForm (...)' для основной формы. В противном случае структура VCL не будет знать, что есть основная форма. Вы действительно делаете DI для основной формы? Это точно хорошая идея? –
Я думал, что это было, пока вы не спросили ... Я думаю, что это хорошая идея, потому что в главном представлении может быть несколько зависимостей, которые нужно было бы решить. Это могут быть просмотры фабрик (TFunc или ленивые виды TLazy ). И выполнение DI на этом облегчит процесс тестирования. –
Ludo
Почему это плохая идея? – Ludo