2015-12-15 2 views
2

Мне нужно засеять базу данных приложения пользователями по умолчанию. Я не использую Entity Framework в этом проекте, вместо этого я решил использовать Dapper.Обработка инъекции зависимостей при посеве базы данных

Простейшая вещь, которую я могу сделать, это иметь простой класс, как DatabaseConfig (или AccountsConfig) с Seed() статический метод:

public class DatabaseConfig { 

    public static void Seed() { 

     using(var conn = new SqlConnection()) { 

      conn.ConnectionString = GetConnectionString(); 
      conn.Open(); 

      var query = "insert into users (username, [password]) values (@username, @password)"; 

      var queryParams = new { 
       username = "Admin", 
       password = HashedPassword.CreateHash("DefaultSecretKey") 
      } 

      conn.Execute(query, queryParams); 
     } 

    } 

    private static string GetConnectionString() { 
     return ConfigurationManager.ConnectionStrings["appDb"].ConnectionString; 
    } 
} 

, а затем вызвать его в Global.asax:

DatabaseConfig.Seed(); 

у меня есть две зависимости здесь:

  1. Я звоню в ConfigurationManager, чтобы получить строку соединения. Я не знаю, плохо ли это. Для других услуг, которые я использую в приложении я передаю строки подключения в качестве параметров конструктора в SimpleInjector инициализаторе:

    private static void InitializeContainer(Container container) { 
    
        var appDbConnString = ConfigurationManager.ConnectionStrings["appDb"].ConnectionString; 
        container.RegisterSingleton<IUsersRepository>(new UsersRepository(appDbConnString)); 
    
    } 
    
  2. Другая зависимость является HashedPassword класса. Я не ожидаю, что он со временем изменится, но все же это зависимость. Должен ли я разрешить это? Как мне его решить?

ответ

4

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

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

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

Другая зависимость - класс HashedPassword. Я не ожидаю, что он со временем изменится, но все же это зависимость. Должен ли я разрешить это?

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

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

1

Вы получаете доступ к HashedPassword и ConfigurationManager статическим способом, это означает, что вам нужно изменить их на нестатические классы, чтобы их вливать. это может быть сделано путем их изменения (что может быть невозможно, это не ваши классы) или для их переноса в класс экземпляра.

Смежные вопросы