Используя Ninject, если я создаю пользовательского поставщика, я должен гарантировать единственный экземпляр, или я могу использовать атрибут SingleInstance?

Я надеюсь или Peter или Ruben видят этот вопрос, поскольку они, кажется, движение парням относительно Ninject. Я должен был создать пользовательского поставщика, потому что у меня есть класс, который берет 4 аргумента. Эти два могут быть введены, потому что они - типы, но другие два являются параметрами конфигурации и являются целыми числами. Они обращаются к тайм-аутам в миллисекундах.

[SingleInstance]
MyClass
{
    ISomething something;
    IOther other;
    int timeout;
    int delay;

    [Inject]
    MyClass(ISomething something, IOther other, int timeout, int delay)
    {
        this.something = something;
        this.other = other;
        this.timeout = timeout;
        this.delay = delay;
    }
}    

Я ранее полагался на фабрику, которую я создал, чтобы получить настройки конфигурации для тайм-аута и задержки и ввести что-то и другой. Теперь это, кажется, разбирается в этом, я должен был бы создать своего собственного поставщика. С которым я хорошо.

Несколько точек дополнительных очков:

  1. Я знаю, что мог использовать инжекцию на параметрах. Но это создает обманчивый API. Объекты должны быть возвращены в готовом для использования состояния, и без тех 4 аргументов это не готово использовать.
  2. Тот же аргумент относится к инжекции метода.

Так, мои заключительные вопросы:

  • Это означает, что я управляю обеспечением единственного экземпляра снова, или Ninject будет все еще заботиться о нем через [SingleInstance] атрибут?
  • Я не должен только переключаться назад на фабрику, которую я имел? Что я получаю от использования Ninject в этом случае?

ОБНОВЛЕНИЕ: Пример кода согласно просьбе

Затем мой поставщик, которого я принимаю, хотел бы что-то вроде этого:

class MyClassProvider : SimpleProvider<MyClass> {
protected override MyClass CreateInstance(IContext context) {
    int timeout= ConfigurationManager.AppSettings.Get("timeout");
    int delay= ConfiguraionManager.AppSettings.Get("delay");
    ISomething something = new SomethingImpl();
    IOther other = new OtherImpl();
    MyClass newOne = New MyClass(something, other, timeout, delay);
    }
}

Но потому что я теперь использую поставщика, делает механизмы того обходного ninject обеспечения только единственного экземпляра объекта, создается, так сделайте я должен возвратиться:

class MyClassProvider : SimpleProvider<MyClass> {

    protected static readonly MyClass myClassInstance;
    private static object locker = new object();

    protected override MyClass CreateInstance(IContext context) {
        if (myClassInstance == null) 
        {
            lock (locker)
            {
                int timeout = ConfigurationManager.AppSettings.Get("timeout");
                int delay = ConfiguraionManager.AppSettings.Get("delay ");
                ISomething something = new SomethingImpl();
                IOther other = new OtherImpl();
                MyClass newOne = New MyClass(something, other, timeout, delay );
            }
            return MyClassInstance
        }
        return myClassInstance
    }
}

Есть ли что-то, что я пропускаю?

6
задан uriDium 25 February 2010 в 12:13
поделиться

2 ответа

Это происходило раньше, и я решил это, создав новое виртуальное устройство, как предлагает мистер Хедлунд. Я не тратил время, пытаясь выяснить, почему это произошло, но создание нового устройства позволило загрузить приложение. Мое приложение почти в два раза больше вашего, и оно прекрасно загружается большую часть времени. Попробуйте удалить и заново создать эмулятор, как предлагает мистер Хедлунд. Это сработало для меня несколько раз... Будучи новичком в разработке Android, я подозреваю, что столкнулся с этой проблемой из-за утечек ресурсов, но я еще не устранил проблему, потому что все еще концентрируюсь на том, чтобы мое приложение работало правильно... Надеюсь, это поможет!

-121--2372717-

«метод доступа по умолчанию» - это специальное свойство, возвращающее объект коллекции на основе его индекс. Например:

[Serializable()]
public class IntList : ICollection {

    // Default Accessor Implementation
    public int this[int index] {
        get {

            return 0;
        }
        set { /* Do Nothing */ }
    }
}

Поэтому невозможно реализовать это в существующем классе сторонних производителей. Используя xml, преобразовывающий в последовательную форму для ApplicationSettings, очень плохая идея, использование Экономят (), Перезагружают () и Сброс () методы или используют ваше собственное, не полученное из классов ApplicationSettingsBase CustomConfiguration.

-121--4460111-

Честно говоря, у меня проблемы с пониманием вашего вопроса - возможно, образец кода того, как вы его создаете, может помочь (ваш вопрос, как правило, хорошо сформулирован). Но вот удар.

Не уверены, что вы имеете в виду под SingleInstance - откуда это? (Я фактически не знал о SingletonAttribute в версии 1, но вижу, что это не в 2,0 Core). Хотя это имеет смысл в некоторых сценариях, я определенно не буду использовать атрибуты поведения в классах в качестве подхода по умолчанию (то есть поместить его в определения привязки вместо).

Я бы все еще пытался использовать провайдера (или Bind < T >. Чтобы * перегрузить лямбду как способ записи фабрики в меньшем количестве кода), особенно потому, что слой поведения экземпляра может быть использован поверх него, и вы будете получать все ваши объекты таким же образом, что хорошо.

Другое предложение, которое я бы сделал, состоит в том, что ваши параметры тайм-аута и задержки, вероятно, можно сделать гражданами первого класса вашего дерева DI, как, например, вещь IConningPolicy , которая может использоваться в нескольких классах.

1
ответ дан 17 December 2019 в 07:03
поделиться

Вы, ребята, неплохо поговорили, но я подумал, что добавлю ответ, который поможет прояснить ситуацию на основе исходного вопроса.

Короткий ответ заключается в том, что Ninject по-прежнему будет гарантировать, что у вас есть единственный экземпляр объекта, если вы укажете . Используя в своем операторе привязки, независимо от механизма активации - т. Е. Вы делаете не обходить механизмы Ninject, гарантирующие создание только одного экземпляра объекта при использовании вашего собственного провайдера с использованием синтаксиса .ToProvider - или синтаксиса .ToMethod , если на то пошло.

Вы должны просто написать своего провайдера для предоставления экземпляров объекта - никакая другая семантика у провайдера не навязывается. Таким образом, вся типичная слизь, необходимая для создания экземпляров singleton, как вы указали в приведенном выше примере, не требуется.

Например, ваш провайдер становится намного проще; хотя я добавил разрешение ISomething и IOther с использованием ядра Ninject в ваш исходный пример:

class MyClassProvider : SimpleProvider<MyClass> {

  protected override MyClass CreateInstance(IContext context) {
    int timeout = ConfigurationManager.AppSettings.Get("timeout");
    int delay = ConfiguraionManager.AppSettings.Get("delay ");
    ISomething something = context.Kernel.Get<ISomething>();
    IOther other = context.Kernel.Get<IOther>();
    return new MyClass(something, other, timeout, delay );
  }
}

Ваш оператор привязки в вашем модуле Ninject будет выглядеть следующим образом:

public class MyModule : StandardModule {
  public override void Load() {

    Bind<IMyClass>()
      .ToProvider<MyClassProvider>()
      .Using<SingletonBehavior>();
  }
}

При использовании SingletonBehavior Ninject по-прежнему предоставит вам только один экземпляр MyClass, даже если вы используете своего собственного провайдера.

Это довольно легко проверить.Вы можете добавить свойство DateTime в свой класс, установить для него значение DateTime.Now в конструкторе и изучить объекты, возвращаемые несколькими вызовами Get () - все они будут иметь одинаковое время, даже если вы создал класс в вашем провайдере. Затем измените Using на Using и обратите внимание на разницу. Каждый раз вы будете получать новый, созданный вашим провайдером.

Надеюсь на эту помощь - кстати, не уверен, что я тот Питер, о котором вы говорили, но если да, то я польщен!

3
ответ дан 17 December 2019 в 07:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: