У меня есть абстрактный завод, который создает некоторую услугу, представленную интерфейсом IService
. На заводе у меня есть два метода Create
, потому что на одном из них я разрешаю потребителю передать существующий экземпляр IServiceLogger
, который будет использоваться построенным деревом службы.Передайте экземпляр зависимостей параметру фабричного метода, чтобы сделать Ninject используемым в разрешении
public interface IMyServiceFactory {
IMyService Create(IServiceLogger loggerInstance);
IMyService Create();
}
Поскольку IServiceLogger
должны быть распределены между деревом службы, я использую InCallScope
при связывании его конкретной реализации.
Как реализовать этот сценарий с помощью Ninject? Я пробовал следующие подходы.
1. Вручную создать реализацию фабрики
internal class MyServiceFactory : IMyServiceFactory {
private IResolutionRoot _kernel;
public MyServiceFactory
public IMyService Create(IServiceLogger loggerInstance) {
// what should go here? how can I pass the existing instance to Ninject Get method and make Ninject to use it for the whole resolution tree, just as it were created by Ninject and used as InCallScope?
}
// this one is trivial...
pulbic IMyService Create() {
return _kernel.Get<IMyService>();
}
}
UPDATE
На самом деле я нашел грязный и не слишком безопасный способ для этого. Я могу получить текущие привязки через GetBindings
, затем Rebind
IServiceLogger
ToConstant
, затем Get
экземпляр IMyService
и, наконец, восстановить оригинальные привязки с помощью AddBinding
. Мне это не нравится, оно кажется вонючим и, что еще хуже, оно не является потокобезопасным, потому что другой поток может запросить IMyService
в середине этого кода и, следовательно, использовать локальную временную привязку.
2. Использование Ninject.Extensions.Factory
Просто используйте ToFactory
связывания, но это не работает, потому что он просто пытается использовать параметр как простой аргумент конструктора (если применимо), а не как объект для всего дерева разрешений.
Благодарим за ответ. То, что вы описали, довольно простое и даже не нуждается в коде IMO, поскольку, поскольку простые одноуровневые аргументы конструктора идут, расширение Factory выполняет задание (как я упоминал в своем сообщении). Проблема возникает, когда 1: регистратор МОЖЕТ быть дополнительным. 2. Регистратор должен использоваться полным деревом службы, а не только на верхнем уровне. Однако я нашел решение, скоро опубликую его. –
О, хорошо. Тогда я бы рекомендовал использовать условное связывание, которое довольно сильно в ninject. –