Уровень обслуживания приложений как статические классы - PullRequest
9 голосов
/ 17 февраля 2010

В моем приложении ASP.NET MVC у меня есть проект, который содержит всю бизнес-логику / сервисный уровень.Этот проект взаимодействует с моей базой данных (платформой Entity), которая находится в отдельном проекте.

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

 ServiceLayer.Accounts.CreateAccount(userName, passWord) //etc..

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

    private static AllRepos _Repos;
    private static AllRepos Repos { 
       get 
        { 
           if(_Repos == null)
              _Repos = new AllRepos();

           return _Repos
        }
    }

    public static void CreateAccount(string username, password)
    {
        string salt = GenerateSalt();
        Account newAccount = DatabaseLayer.Models.Account
              { 
              Name = username,
              Password = HashPassword(password, salt),
              Salt = salt
              };
        Repos.AddAccount(newAccount);      
    }

Поскольку я не хотел делать следующее повсюду на своем уровне обслуживания:

 AccountRepository Accounts = new DatabaseLayer.AccountRepository();

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

 public class AllRepos
 {

    private AccountRepository _Accounts;

    public AccountRepository Accounts
    {
        get
        {
            if (_Accounts== null)
                _Accounts= new AccountRepository();

            return _Accounts;
        }
    }

    // the same is done for every other repository (currently have about 10+)
  }

, который использовался в статических классах уровня обслуживания.

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

Я понимаю, что этого следует ожидать, если я буду использовать статические члены / классы, как я делал, так как они имеют последний жизненный цикл приложения, но есть ли возможность использовать уровень обслуживания как ServiceLayer.Accounts.Method()без необходимости создания нестатического класса, который необходимо создавать везде, где он используется, и не сталкиваться с проблемами CRUD из-за нескольких экземпляров datacontext?

Ответы [ 4 ]

15 голосов
/ 17 февраля 2010

Ваш подход к этому действительно не рекомендуется.Лично я бы никогда не допустил такого подхода в моей команде.Недостатки:

  1. Основные проблемы с многопоточностью, которые вы испытываете, которые не так просто решить
  2. Вы не можете проверить это очень легко.
  3. Нереалистичная абстракциявашего доступа к данным

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

Вы должны просто сделать свойинстанцирование репозитория как часть ваших базовых классов обслуживания в любом случае.Нет причины, по которой это должны быть «статические ИЛИ вызовы экземпляров везде».В базовых классах должен быть ограниченный экземпляр кода экземпляра.

10 голосов
/ 17 февраля 2010

Я не уверен, почему вы так решительно настроены против использования инстансов. Помимо того, что код, который у вас сейчас есть, излишне сложен, использование статических типов также усложняет юнит-тестирование. Статический тип похож на одноэлементный, который нельзя смоделировать / заменить. Мне кажется, что ваш реальный вопрос может быть: «Как мне управлять экземплярами уровня обслуживания на протяжении всей жизни?» Как правило, вы делаете это, имея один экземпляр на веб-запрос. В приложении ASP.NET MVC вы можете создать контейнер DI через ControllerFactory и обрабатывать все это. [PDF]

1 голос
/ 17 февраля 2010

Вам необходимо продуманно управлять областью действия вашего объектного контекста, например,

*1001*.

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

Я могу сказать это, сжег себя, делая подобные вещи ранее:)

0 голосов
/ 17 февраля 2010

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

...