Шаблон репозитория единиц работы для статического класса - PullRequest
0 голосов
/ 06 февраля 2019

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

статический класс

 using System;
  using System.Data.SqlClient;

  namespace Contoso
  {
    public static class UsersRepository
    {
        private static string ConnectionString = @"Data Source=(local);    Database=Users;User Id=sa;Password=password;";

        public static User Load(int userId)
        {
            User user = new User();

            SqlConnection connection = new SqlConnection(ConnectionString);
            connection.Open();

            SqlCommand command = new SqlCommand("SELECT * FROM Users WHERE UserId = " + userId,
                connection);
            var reader = command.ExecuteReader();

            while (reader.Read())
            {
                user.Name = reader["Name"].ToString();
                user.DateOfBirth = DateTime.Parse(reader["DateOfBirth"].ToString());
                user.Country = reader["Country"].ToString();
            }

            connection.Close();

            return user;
        }
    }
}

1 Ответ

0 голосов
/ 06 февраля 2019

Как я могу реализовать единицу работы и шаблон репозитория для статического класса?

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

Что-то вроде:

public static class MyClass
{
    public static User LoadUser(int userId)
    {
        using (var uow = new UnitOfWork())
        {
            DoSomething(uow);

            var user = uow.UserRepository.GetById(userId);

            return user;
        }
    }
}

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

  • Параллельные вызовы используют свою собственную отдельную единицу работы.
  • Никакая единица работы никогда не задержится в памяти после завершения метода ввода.

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


Мне нравится реализовывать решение, применяянадежные принципы и тестируемое приложение

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

Таким образом, внедрение вашей зависимости будет ... нетипичным.Одно из решений, которое я могу придумать, - это явно установить ядро ​​(я использую здесь NInject в качестве примера):

public static class MyClass
{
    public static IKernel Kernel { get; set; }

    public static User LoadUser(int userId)
    {
        using (var uow = Kernel.Get<IUnitOfWork>())
        {
            DoSomething(uow);

            var user = uow.UserRepository.GetById(userId);

            return user;
        }
    }
}

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

Без NInject или любой другой подобной библиотеки вы можете добиться внедрения зависимости, используя Func<IUnitOfWork> в качестве заводского метода для создания единицы работы по требованию:

public static class MyClass
{
    public static Func<IUnitOfWork> CreateUnitOfWork { get; set; }

    public static User LoadUser(int userId)
    {
        using (var uow = CreateUnitOfWork())
        {
            DoSomething(uow);

            var user = uow.UserRepository.GetById(userId);

            return user;
        }
    }
}

Опять же, как вы устанавливаетезаводской метод зависит от вас, например:

MyClass.CreateUnitOfWork = () => new UnitOfWork();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...