Это вполне возможно сделать в Ninject, просто так не получается, как разрешение ведет себя по умолчанию.Расширение IKernel.Get<T>
не запрашивает привязку «по умолчанию», оно запрашивает привязку any ;другими словами, он не применяет никаких ограничений.Если существует более одной совпадающей привязки, то он генерирует исключение для этого эффекта.
Попробуйте эти два метода расширения:
static class KernelExtensions
{
public static T GetDefault<T>(this IKernel kernel)
{
return kernel.Get<T>(m => m.Name == null);
}
public static T GetNamedOrDefault<T>(this IKernel kernel, string name)
{
T namedResult = kernel.TryGet<T>(name);
if (namedResult != null)
return namedResult;
return kernel.GetDefault<T>();
}
}
Первый получает привязку «по умолчанию», т.е.Кого бы вы ни связали, у которого нет имени .Второй пытается получить именованную привязку, но если он этого не находит, он возвращается к значению по умолчанию.
Конечно, Remo также не ошибается;вам следует избегать использования Ninject или любого другого контейнера таким образом, если у вас нет для этого особых причин.Это шаблон локатора служб (анти), а не внедрение истинных зависимостей.Вы должны использовать синтаксис When
для условных привязок, либо использовать сложные условия, либо просто декорировать классы, которые требуют специальных привязок, то есть:
Bind<IFoo>().To<SpecialFoo>().WhenInjectedInto<ClassThatNeedsSpecialFoo>();
или ...
Bind<IFoo>().To<SpecialFoo>().WhenMemberHas<SpecialAttribute>();
class InjectedClass
{
public InjectedClass([Special]IFoo) { ... }
}
Это правильный способ обработки стандартных и условных привязок.Именованные привязки действительно полезны только тогда, когда вы пытаетесь реализовать фабричный шаблон и хотите обернуть контейнер IoC на своей собственной фабрике.Это нормально, но, пожалуйста, используйте его экономно, так как в конечном итоге вы выбрасываете многие / большинство преимуществ внедрения зависимостей таким образом.
В качестве альтернативы, вы можете реализовать собственное поведение активации и использовать его дляпереопределить значение по умолчанию в Ninject - все является модульным и попадает в коллекцию «Компоненты».Но это не для слабонервных, поэтому я не планирую включать здесь подробное руководство.