SimpleIoc - может ли он каждый раз предоставлять новый экземпляр? - PullRequest
18 голосов
/ 18 февраля 2012

Насколько я понимаю, SimpleIoc использует метод GetInstance для извлечения экземпляра зарегистрированного класса.Если экземпляр не существует, он создаст его.Однако этот экземпляр кэшируется и всегда извлекается, что имитирует шаблон синглтона.

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

public MyViewMOdel MyViewModel
{
    get { return SimpleIoc.Default.GetInstance<MyViewModel>(); }
}

, в этом используется шаблон синглтона, что, я думаю, не является наилучшей практикой во всех случаях.Чтобы обойти эту проблему, я делаю это:

public MyViewModel MyViewModel
{
    get { return new MyViewModel(SimpleIoc.Default.GetInstance<ISomeInterface>()); }
}

У этого есть недостаток, заключающийся в том, что если я когда-либо изменю конструктор для MyViewModel, мне нужно будет также обновить это свойство.Ничего страшного, но все же есть какая-то зависимость.

Как вы справляетесь с этим сценарием, и я что-то упускаю?и почему было решено не возвращать неиспользуемый экземпляр.

И еще один вопрос: в сеансе глубокого погружения MVVM Лоран использует метод GetInstance сразу после регистрации определенной ViewModel, чтобы, как он говорит,убедитесь, что в контейнере уже есть экземпляр этой ViewModel.Почему именно это необходимо?Если вы выбираете ViewModel через ViewModelLocator, вы создадите его при необходимости.Так почему я хочу, чтобы они были созданы заранее?

Ответы [ 3 ]

9 голосов
/ 19 февраля 2012

Вы можете каждый раз получать разные экземпляры, передавая разные ключи методу GetInstance. Однако экземпляры будут кэшироваться, поэтому, если вы не хотите хранить их в кэше, вам необходимо вызвать Unregister с соответствующим ключом.

В демоверсии я создавал виртуальную машину заранее, потому что MainVM отправлял сообщения на SecondaryVM. Поскольку регистрация в Messenger выполняется в конструкторе SecondaryVm, его необходимо создать, прежде чем он сможет начать получать сообщения. Messenger великолепен, потому что он очень отделен, но это один из следующих случаев, когда вам нужно проделать дополнительную работу, чтобы компенсировать разделение: SecondaryVM является целью сообщений, даже если MainVM не получает на него никаких ссылок. *

Надеюсь, это имеет смысл. Ура, Laurent

2 голосов
/ 05 апреля 2017

После борьбы с SimpleIoC для предоставления новых экземпляров каждый раз, когда запрашивается определенный тип, и обнаружение, что эта функция не реализована (принятый выше метод на основе ключей не подходит для сценариев, где вы хотите сказать, выполнить операцию базы данных и выбрасывать соединение каждый раз), я нашел относительно приличное решение, сочетающее IoC с шаблоном Factory: Создайте класс, который отвечает за создание новых экземпляров определенного типа с помощью функции:

class MyObjectFactory: IMyObjectFactory
{
    public MyObject CreateObject()
    {
        return new MyObject();
    }
}

Создание интерфейса для фабричного класса MyObject:

public interface IMyObjectFactory
{
    MyObject CreateObject();
}

Затем настройте контейнер IoC для предоставления фабрики любым классам, которые используют экземпляры MyObject:

SimpleIoc.Default.Register<IMyObjectFactory, MyObjectFactory>();

Теперь любой класс, требующий нового экземпляра MyObject, объявит свое требование MyObjectFactory (вместо требования MyObject) в конструкторе для внедрения конструктора:

public class MyObjectUser
{
    MyObject _myObject;
    public MyObjectUser(IMyObjectFactory factory)
    {
        _myObject = factory.CreateObject();
    }
}

Таким образом, я думаю, что вы не связаны ограничениями фабричного шаблона и обладаете всеми преимуществами контейнеров IoC и инжекторов Constructor, что также позволяет обойти ограничение SimpleIoC.

2 голосов
/ 18 февраля 2012

SimpleIOC - это то, что это ... простой контейнер IOC. У него будут некоторые недостатки ... но вы не связаны с ним, вы всегда можете использовать другой контейнер ICO (например, Unity, Autofac, Castle, ...).

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

Однако, помните , вы не обязаны использовать отдельный контейнер с MVVM . В нескольких моих проектах я использовал Unity, но каждый другой контейнер IOC будет одинаково хорошо, это вопрос требований, предпочтений клиента и - если все остальное не удастся - просто старый personal gusto.

...