Хранение глобальных неизменяемых данных в статических классах - PullRequest
1 голос
/ 22 сентября 2011

У меня есть проект WinForms, который использует много пользовательских элементов управления. Некоторые из этих пользовательских элементов управления используют классы из уровня бизнес-логики. Эти классы в основном выполняют операции CRUD с базой данных (через уровень доступа к данным), а также выполняют некоторые дополнительные проверки и отчеты.

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

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

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

Или вы знаете какой-нибудь другой подход, который мог бы помочь мне избавиться от всего кода инициализации?

Ответы [ 4 ]

2 голосов
/ 22 сентября 2011

Вы можете использовать Inversion of Control контейнер, такой как Unity или Autofac , и он автоматически соединит ваш объектный граф для вас.

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

Пример внедрения свойства с Unity:

public class MyUserControl : UserControl 
{
    [Dependency]
    public LoggedUserService UserService { get; set; }

    public void Method()
    {
        // the IoC container will ensure that the UserService
        // property has been set to an object
    }
}

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

1 голос
/ 22 сентября 2011

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

public sealed class Singleton
{
    public object Property1 {get;set;}
    public void Method1 (){}

    static Singleton instance = null;
    static readonly object padlock = new object();

    Singleton()
    {
    }

    public static Singleton Instance
    {
        get
        {
            lock (padlock)
            {
                if (instance==null)
                {
                    instance = new Singleton();
                }
                return instance;
            }
        }
    }        
}

тогда вы можете использовать его как статичное, но немного другое ...

public class Main
{
     public Main()
     {
         Singleton.Instance.Property1 = "somevalue";
         Singleton.Instance.Method1();
     }

}
1 голос
/ 22 сентября 2011

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

0 голосов
/ 22 сентября 2011

Вы можете использовать статический класс для хранения некоторых неизменяемых данных - с этим нет проблем. Однако если вы хотите хранить там элементы управления, они могут работать не так, как ожидалось. Например, такой метод, как OnDataBinding и Render.

...