Внедрение зависимостей в указанный проект

Я пытался чего-то добиться с помощью Ninject (без большого понимания библиотеки) и понял, что может быть невозможно делать то, что я хочу.

У меня есть один из наших собственных проектов, на который я ссылался, и я пытался использовать Ninject для добавления некоторых зависимостей, например:

public class ImageHelper
{
        [Inject]
        public static AdaptiveImageSettings Settings { get; set; }

        [Inject]
        public static IImageSizerFactory Factory { get; set; }
    }
}

Цель состоит в том, чтобы иметь некоторые настройки (которые могут обслуживаться разными классами) и фабрику, которая может создавать экземпляры класса ImageHelper. Я не слишком зациклен на том, что статично, а что нет прямо сейчас.

Если я попытаюсь использовать свой ImageHelper из веб-приложения, ссылающегося на этот проект, эти свойства всегда будут нулевыми. Со страницы в моем веб-приложении со следующими зависимостями вводятся нормально:

 public partial class _Default : Page
 {
        protected void Page_Load(object sender, EventArgs e)
        {

        }

        [Inject]
        public NetC.Core.ImageSizer.IImageSizerFactory Factory { get; set; }
 }

Из того, что я прочитал, это связано с тем, что ядро ​​​​обрабатывается автоматически, но я не могу найти способ получить доступ к ядру, чтобы я мог разрешить эти свойства. Может ли кто-нибудь дать мне несколько советов о том, что, если это разумно возможно, или каким может быть следующий шаг? До сих пор я видел только анти-шаблон ServiceLocator и не мог найти расширения, которое отвечало бы всем требованиям.


person Ian    schedule 02.06.2014    source источник
comment
Как вы решаете проблему Factory на своей странице? Потому что это выглядит странно — вы, кажется, утверждаете, что Ninject успешно разрешает фабрику, но не разрешает ее внутренние зависимости. Конечно, эти свойства статичны, поэтому Ninject не хочет их трогать. Вы пытались иметь там свойства экземпляра?   -  person Wiktor Zychla    schedule 02.06.2014
comment
@WiktorZychla: фабрика разрешается только с помощью InjectAttribute (у меня, очевидно, есть KernelBinds в другом месте в NinjectWebCommon). Но я предполагаю, что Ninject что-то делает на странице, но «знает» или «перехватывает» запросы на ImageHelper? Я пытался создать экземпляр свойств на основе этого, это не имело никакого значения.   -  person Ian    schedule 02.06.2014
comment
Ninject знает об этом, потому что дополняет OnPageInitComplete простым вызовом kernel.Inject(page), как описано здесь. stackoverflow.com/questions/4933695/ Однако разрешение зависимости свойств должно по-прежнему работать рекурсивно, и поэтому я понятия не имею, почему свойства экземпляра вашего вспомогательного изображения не разрешаются. Моя идея состояла бы в том, чтобы попробовать инъекцию конструктора. Не могли бы вы попробовать и отчитаться?   -  person Wiktor Zychla    schedule 02.06.2014
comment
Проблема может заключаться в рекурсии — на данный момент ImageHelper не находится на странице.   -  person Ian    schedule 02.06.2014


Ответы (2)


Похоже на плохой вариант использования для любого контейнера.

Просто назначьте их вручную при запуске приложения

person jgauffin    schedule 02.06.2014

Вы должны перейти к внедрению конструктора:

public class ImageHelper
{
    private readonly AdaptiveImageSettings settings;
    private readonly IImageSizerFactory factory;

    public ImageHelper(AdaptiveImageSettings settings, IImageSizerFactory factory) {
        this.settings = settings;
        this.factory = factory;
    }
}

Когда вы запрашиваете ImageHelper у Ninject, ninject автоматически вводит соответствующие зависимости в свой конструктор. Конструктор имеет множество преимуществ, таких как:

  • Он явно указывает, что требуется для типа, и становится контрактом.
  • Определяющий тип не должен ничего знать об образе жизни зависимостей (в то время как ваш ImageHelper заставляет свои зависимости быть одноэлементными).
  • О зависимостях нельзя забывать (они требуются конструктору).

Поэтому всякий раз, когда вы можете, используйте внедрение конструктора как можно чаще.

person Steven    schedule 03.06.2014
comment
Однако, конечно же, Ninject должен знать об экземпляре? Например, контроллеры MVC, разве он не перехватывает их конструкцию, чтобы разрешить разрешение зависимостей? - person Ian; 03.06.2014
comment
@Ian: Ninject иногда может разрешать незарегистрированные типы (например, ImageHelper, потому что он конкретен), но обычно лучше явно зарегистрировать все. Итак, вы должны зарегистрировать (связать) ImageHelper, AdaptiveImageSettings и IImageSizerFactory. - person Steven; 03.06.2014
comment
Не могли бы вы объяснить привязку немного подробнее? В настоящее время у меня есть определения привязки по строкам kernel.Bind<IImageSizerFactory>(new ImageSizerFactory()), вы как-то имеете в виду регистрацию свойств ImageHelper? - person Ian; 09.06.2014