Подтвердить что ты не робот

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

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

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

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

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

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

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

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

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

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

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

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

Ответ 3

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

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

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

public interface IMyObjectFactory
{
    MyObject CreateObject();
}

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

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

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

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

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