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");