MVVM разделяет объект между всеми представлениями - PullRequest
2 голосов
/ 27 декабря 2010

У меня есть проект MVVM, и я хочу разделить один объект (синглтон) из модели между несколькими моделями представления. Что такое хорошая практика для этого? Спасибо за помощь

Ответы [ 4 ]

3 голосов
/ 27 декабря 2010

Если объект необходим и не предоставляет значения без него, принудительно установите интерфейс внутри объекта через Конструктор Инъекция ; не проталкивайте конкретный тип через инъекцию, всегда используйте интерфейс.

Поскольку вы не используете контейнер IoC, такой как Unity , вам нужно будет создать свой экземпляр singleton при запуске приложения, а затем убедиться, что данный экземпляр передается через предоставляется конструктор ViewModels по мере необходимости.

Лучшим подходом было бы подтолкнуть экземпляр синглтона к сервису, который может обеспечить необходимое поведение, а затем игнорировать добавление синглтона в модель. Это будет более пуристический подход MVVM и разделит проблемы между вашими Моделями / ViewModels.

РЕДАКТИРОВАТЬ:

Если вы используете Unity, вы определите Lifetime Manager во время регистрации.

// Register a type to have a singleton lifetime without mapping the type
// Uses the container only to implement singleton behavior
myContainer.RegisterType<MySingletonObject>(new ContainerControlledLifetimeManager());
// Following code will return a singleton instance of MySingletonObject
// Container will take over lifetime management of the object
myContainer.Resolve<MySingletonObject>();

Как только вы сделаете это, любая попытка разрешить MySingletonObject через IUnityContainer приведет к тому же экземпляру, обеспечивающему одноэлементное поведение, которое вы так желаете во всем приложении. Самим ViewModels не нужно возвращать один и тот же экземпляр. Необходимые данные должны быть извлечены с помощью службы, на которую ссылались ранее, которая потенциально может вести себя как одноэлементная и предоставлять реализацию с сохранением состояния, если это необходимо, но ViewModel не должна быть одиночной. Если вы обнаружите, что делаете Model или ViewModel синглтоном; сделайте шаг назад и проанализируйте свой дизайн.

2 голосов
/ 27 декабря 2010

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

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

Примерно так я и использовал в своих проектах:

public class MyViewModelBase : INotifyPropertyChanged
{
    private static MySharedSingleton _sharedObj;
    static MyViewModelBase()
    {
        _sharedObj = new MySharedSingleton(/* initialize it here if needed */);
    }
    // or public
    protected MySharedSingleton SharedObject { get { return _sharedObj; } }

    // INotifyPropertyChanged stuff
    // ...
}

public class SomeViewModel : MyViewModelBase
{
    void SomeMethod()
    {
        SharedObject.DoStuff();
    }
}

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

1 голос
/ 27 декабря 2010

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

0 голосов
/ 30 ноября 2013

Я использую отдельный класс для моего глобального синглтона с моделью.Это избавляет меня от мучений по поводу того, как внедрить эту модель в модели представлений и другие модели.Например,

Синглтон:

public class ApplicationModel
{
    public string LoggedOnUser { get; set; }
    // Etc.

    private ApplicationModel() {
        // Set things up.
    }

    private static ApplicationModel _active;
    public static ApplicationModel Current {
        get {
            if (_active == null) {
                _active = new ApplicationModel();
            }
            return _active;
        }
    }
}

Модель представления, которая не должна содержать ссылки на синглтон:

public class SomeViewModel
{
    private string _user;
    public SomeViewModel() {
        _user = ApplicationModel.Current.LoggedOnUser;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...