Ninject передача значений конструктора
С Ninject, как вы настраиваете ядро, чтобы я мог определить, какие значения конструктора передаются в экземпляр объекта?
У меня в модуле настроено следующее:
Bind<IService1>()
.To<Service1Impl>()
.InSingletonScope()
.Named("LIVE");
Bind<IService2>()
.To<Service2Impl>()
.InSingletonScope()
.Named("LIVE")
.WithConstructorArgument(
"service1",
Kernel.Get<IService1>("LIVE"));
Service2Impl принимает параметр конструктора IService1, но я хочу, чтобы это исходило из контейнера. Я также хочу иметь именованные привязки, поскольку мой код будет нацелен на разные версии во время выполнения.
Это, кажется, работает, но это правильный путь достичь того, чего я хочу? Должен ли я достигать без использования именованных Привязок и подключения различных модулей конфигурации в ядро?
редактировать
теперь я использовал метод ToMethod (), чтобы указать делегат для вызова по запросу определенного типа. Это кажется немного приятнее, так как я получу предупреждения времени компиляции, если конфигурация конструктора неверна, а не знать имя параметра, который я передаю первый.
спасибо
5 ответов
Я бы рекомендовал WithConstructorParameter
перегрузка, которая принимает лямбду так:
Bind<IService2>()
.To<Service2Impl>()
.InSingletonScope()
.Named("LIVE")
.WithConstructorArgument(
"service1",
ctx => ctx.Kernel.Get<IService1>("LIVE"));
это гарантирует, что разрешение IServive1
происходит в момент активации Service2Impl
, а не при запуске при создании контейнера. Хотя в вашем случае это не имеет значения, как Service1Impl
является синглтоном, могут быть побочные эффекты при этом так, как вы изначально его написали:
привязка для зависимости, которая вводится
WithConstructorArgument
есть уже существовать. Это означает, что все привязки должны выполняться в определенном порядке. Это создает может получить сложно, когда есть несколько модулей.проблемы с областью могут возникнуть при использовании настраиваемой области. Ninject 2.0 представил кэш и собирает управление областью, привязка к константе, скорее всего, бросит это в беспорядок.
я использовал ToMethod в конце, что позволило мне построить требуемый экземпляр с конструкторами для поддержания ошибок времени компиляции.
например:
.ToMethod(Func<IContext, T> method)
Bind<IWeapon>().ToMethod(context => new Sword());
кажется, вы смотрите на это неправильно. Ninject автоматически введет службу 1 в службу 2, если она имеет ее в качестве аргумента конструктора. В этом случае нет необходимости в WithConstructorArgument.
Если есть несколько IService1, вы должны пойти на условия. Е. Г. WhenParentNamed(...)
возможно, провайдеры могут вам помочь. Привязка IService2 к поставщику. и в методе Create провайдера используйте Kernel.Get ("LIVE") для создания экземпляра Service2Impl.
см. следующую ссылку, чтобы узнать, как использовать поставщик https://github.com/ninject/ninject/wiki/Providers%2C-Factory-Methods-and-the-Activation-Context
Я думаю ToConstant()
- чище,InSingletonScope
подразумевается:
Bind<IService2>().ToConstant(new Service2Impl(argument)))
.Named("LIVE");