Simpleioc - может ли он предоставлять новый экземпляр каждый раз, когда требуется?

StackOverflow https://stackoverflow.com/questions/9342294

Вопрос

Насколько я понимаю, 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 Deep Dive Session Laurent использует метод GetInstance сразу после того, как он регистрирует конкретную ViewModel, чтобы, как он говорит, убедиться, что в контейнере уже есть экземпляр этой ViewModel. Почему именно это необходимо? Если вы получаете ViewModel через ViewModellocator, то вы создадите его при необходимости. Так зачем мне создать их заранее?

Это было полезно?

Решение

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

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

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

Другие советы

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

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

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

После борьбы с Simpleioc для предоставления новых экземпляров каждый раз, когда запрашивается конкретный тип, и обнаруживает, что эта функция не реализована (метод, основанный на ключе Вдали каждый раз), я придумал относительно приличное решение, объединяющее МОК с заводской шаблоном: создайте класс, который несет ответственность за создание новых экземпляров определенного типа с помощью функции:

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

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

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 и инъекции конструктора, также обходя ограничения Simpleioc.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top