Как сделать объект доступным из любого места, не используя статические методы? - PullRequest
0 голосов
/ 24 апреля 2019

Этот вопрос относится к настольному приложению.

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

Например, в приложении объект User (или что-то подобное) присутствует очень часто.Представьте, что где-то в бизнес-логике используется модель / репозиторий данных, и вам нужен идентификатор пользователя, чтобы передать его в качестве параметра на уровень данных, чтобы он мог загрузить соответствующие данные для пользователя.В большинстве случаев в веб-приложениях я вижу, что такая информация, как идентификатор пользователя, поступает из параметра URL или данных HTTP-публикации и отправляется в контроллер с помощью метода действия.

В настольных приложениях это отличается, посколькувсе «состояние» остается неизменным.Предположим, что пользовательский объект создается один раз при запуске программы и, конечно, хранится где-то в памяти.Как я могу получить к нему доступ из другой части приложения?Кажется, есть только две опции:

  1. Использование статического метода в общем классе, который содержит объект пользователя, который возвращает его.
  2. Внедрение объекта пользователя через все деревоклассы, которым нужен объект.

Я думаю, что оба варианта ужасны и не оптимальны.Поскольку я думаю, что это очень распространенная ситуация, каковы наилучшие методы поддержания хорошей структуры?

Ответы [ 2 ]

0 голосов
/ 24 апреля 2019

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

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

public static class ObjectFactory
{
    public static T GetObject<T>() where T : new()
    {
        return new T();
    }

    public static User GetUserObject(param1, param2)
    {
        // some logic
        ....
        return new User();
    }
}

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

public static class ObjectFactory
{
    private static Dictionary<string, object> collection = new Dictionary<string, object>();

    public static T GetObject<T>() where T : new()
    {
        string key = typeof(T).ToString();

        if (collection.ContainsKey(typeof(T).ToString()))
            return (T)collection[key];

        var instance = new T();

        collection.Add(key, instance);

        return instance;
    }
}

ПроблемаПри использовании инфраструктуры IoC для приложений для настольных компьютеров они не имеют аналогичного времени жизни приложения, как веб-приложение.После запуска приложения сценарий типа «запрос / ответ» отсутствует.Вы бы показывали основную форму, которая, вероятно, может открыть другую форму и т. Д.

Если вы ищете более сложное решение, которое включает разрешение экземпляров форм вместе с зависимостями.Пожалуйста, посмотрите на ответ на возможный повторяющийся вопрос.

Надеюсь, это поможет.

0 голосов
/ 24 апреля 2019

Я не уверен, почему вы думаете, что # 2 "уродлив и не оптимален", но вместо инъекции User объекта, возможно, было бы внедрение IUserService, у которого есть методы для получения текущего пользовательского объекта, было бы подходом к рассматривать.

Я делал подобные вещи в различных приложениях для настольных компьютеров, используя Microsoft Unity , но у вас было бы много вариантов для различных структур DI. Я не уверен, насколько вы знакомы с DI в целом, и существует множество статей, но я нашел достойную отправную точку для этой концепции - Центр разработчиков шаблонов и практик Microsoft с некоторым вступлением. документация по Unity и, конечно, самая последняя документация Unity Container на Git Hub.

Пожалуйста, сделайте еще один пост, если у вас есть конкретные вопросы о том, как реализовать такой шаблон.

...