Привязка синглтона к нескольким сервисам в Ninject - PullRequest
9 голосов
/ 30 июня 2010

У меня есть проблема, которая кажется очень похожей на проблему, описанную в http://markmail.org/message/6rlrzkgyx3pspmnf, которая касается единственного фактического создания более одного экземпляра, если вы обращаетесь к нему с использованием разных типов служб.

Я использую последнюю версию Ninject 2 для Compact Framework, и точная проблема, с которой я сталкиваюсь, заключается в том, что если я привяжу тот же метод провайдера к:

Func<Service> serviceCreator = () => new Service(false);
kernel.Bind<IService>().ToMethod(serviceCreator).InSingletonScope();
kernel.Bind<Service>().ToMethod(serviceCreator).InSingletonScope();

Создается впечатление, что создается 2 экземпляра Сервиса, если я разрешу и IService, и Сервис.

Это вызывает исключение циклической зависимости при разрешении службы.

Это по замыслу или это ошибка?

Ответы [ 3 ]

11 голосов
/ 30 июня 2010

В V3 наконец-то есть решение для этого в виде новых перегрузок на Bind, см. это связано: вопрос .


Если вы хотите, чтобы синглтон был общим, вам нужно изменить свой второй Bind на:

kernel.Bind<Service>().ToMethod(()=>kernel.Get<IService>()).InSingletonScope();

Повторные ссылки и путаница и т. Д. Внутренне неявное самообязание добавит регистрацию неявного связывания для Сервиса. Вы должны опубликовать исключение.

РЕДАКТИРОВАТЬ: Re ваш комментарий. Если вы делаете это так:

Func<Service> serviceCreator = () => new Service(false);
kernel.Bind<Service>().ToMethod(serviceCreator).InSingletonScope();
kernel.Bind<IService>().ToMethod(()=>kernel.Get<Service>()).InSingletonScope();

Тогда не будет сгенерировано неявное самосвязывание классов, когда IService получит Resolved - он использует существующий.

В последние недели здесь, на SO, был еще один вопрос: кто-то делал подобные вещи, но столкнулся с проблемой с IInitializable - этот пример будет иметь правильный порядок, но приведенный выше имеет смысл на основе мое прочтение источника и то, как оно генерирует неявные самосвязывания классов.

5 голосов
/ 08 августа 2012

Кстати, Ninject 3 допускает этот синтаксис :

kernel.Bind<IService, Service>().ToMethod(serviceCreator).InSingletonScope();

Или, аналогично:

kernel.Bind(typeof(IService), typeof(Service)).ToMethod(serviceCreator).InSingletonScope();

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

4 голосов
/ 04 марта 2011

Мы использовали метод Рубена в нашем проекте, но обнаружили, что не было интуитивно понятно, почему вы возвращаетесь к Ядру в своем связывании.Я создал метод расширения и вспомогательный класс (ниже), чтобы вы могли сделать это:

kernel.Bind<IService>().ToExisting().Singleton<Service>();

Это, как мне показалось, более ясно выражало намерение.

...