Где подходящее место для добавления метода для обработки строки подключения SQL в ASP.NET WebAPI

#c# #asp.net #asp.net-mvc #asp.net-web-api

#c# #asp.net #asp.net-mvc #asp.net-веб-api

Вопрос:

У меня есть набор из множества баз данных, которые следуют одной и той же схеме, и я абстрагировал соответствующие таблицы на уровне модели приложения. Я использую SqlConnections для обработки подключения к базе данных, адаптерам данных и таблицам данных для хранения и перемещения информации обратно в контроллеры и через них и т.д. Приведенный ниже код — это то, что я использую в настоящее время, и на данный момент он работает нормально:

 using (SqlConnection con =    
    new SqlConnection(
    "server=MyServersIp\NameofInstance; "  
    "initial catalog=thisisvariable;"  
    "user id=username;"  
    "password=password123;")) { /* Stuff happening here */ }
 

То, что я хотел бы использовать, это что-то более похожее на это здесь:

 using (SqlConnection con =    
    new SqlConnection(getConnectionString("databaseIdentifier")) 
    { 
        /* Stuff  still happening here */ 
    }
 

Итак, я ищу подходящее место для размещения моего метода:

 public string getConnectionString(string databaseIdentifier)
{ 
    String theConnectionStringIneed = "appropriateConnectionString"
    return theConnectionStringIneed; 
}
 

Я очень новичок в MVC и Web API с точки зрения структуры и т.д., и я хочу убедиться, что я следую лучшим практикам.

Мой вопрос в том, куда в стандартной структуре должен идти такой метод? Я хочу, чтобы он был доступен из любого места в надежде сохранить весь процесс строки подключения СУХИМ, но мне также нужно, чтобы он был несколько динамичным (определенный вывод на основе ввода идентификатора базы данных)

Это кажется достаточно простым вопросом, но все, что я могу найти после некоторого специального поиска, — это примеры того, как использовать Entity Framework или людей, генерирующих базы данных из модели и т. Д., Не Используя строки подключения.

Пожалуйста, посоветуйте и, как всегда, спасибо сообществу SO.

Комментарии:

1. К моему ответу также добавлено небольшое примечание о «code first».

Ответ №1:

Это предназначено для ответа на ваш более общий вопрос: «Мой вопрос в том, куда в стандартной структуре должен идти такой метод? » и просто немного расширяет его с некоторыми архитектурными мыслями…

Не уверен, что вы уже это делаете, хотя я бы поместил ваши задачи с базой данных — как и во всех ваших CRUD и подключениях — в собственный проект — уровень доступа к данным в этом случае.. Держите этот проект отдельно от ваших моделей. — Этот вид непосредственно отвечает на ваш первоначальный вопрос «куда он должен идти …»

Затем вы можете добавить ссылку на свой слой модели. (предполагая, что у вас есть все ваши модели в проекте сами по себе)

Это сохраняет эти 2 отдельных. Почему? Что ж, однажды вы можете решить использовать Entity Framework или какое-либо другое средство связи с вашей базой данных. Если это так, то вам нужно только изменить уровень доступа к данным. И вы можете сохранить свои модели блестящими и новыми.

Если вы хотите действительно продвинуть лодку, создайте другой проект, который находится между вашим веб-сайтом и новым уровнем доступа к данным — назовите его services. Это будет вашим посредником между вашей базой данных и вашим веб-сайтом.

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

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

Итак, в терминах непрофессионалов.. Рабочий процесс будет выглядеть примерно так:

  • Пользователь нажимает на ссылку
  • Контроллер веб-сайта получает доступ к выборке данных…
  • Контроллер запрашивает данные у сервисного посредника, но контроллеру требуется только небольшая их часть, поэтому запрашивается небольшая версия (ViewModel)
  • Сервисный посредник говорит: «Хорошо, дай мне секунду ..»
  • Затем сервисный посредник переходит на уровень доступа к данным и говорит: «Дайте мне эти данные» и запрашивает полномасштабную модель (строку из базы данных).
  • Затем посредник получает это обратно с уровня доступа к данным и говорит: «хм .. контроллер сказал, что ему не нужна половина этих свойств ..» поэтому посредник создает экземпляр ViewModel (который вы определили, как модель).
  • Затем посредник заполняет этот экземпляр, модель представления, данными из модели, предоставленной ему уровнем доступа к данным.
  • Посредник может также делать какие-то другие вещи, связанные с деловой логикой..
  • Затем он передает его обратно контролеру и говорит: «Вот так, говнер».
  • Затем контроллер возвращает его в результате своего действия.

И есть забавный маленький способ объяснить это: D

Небольшое замечание на стороне

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

Для этого я бы рекомендовал Entity Framework Powertools. У него есть потрясающий инструмент обратного проектирования, который построит все ваши модели и отношения из вашей базы данных. Чертовски круто!

Комментарии:

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

2. Нет упоминания о внедрении зависимостей, особенно для строки подключения?

3. @X3074861X — серьезно? Вы бы взяли кого-то, кто кажется довольно новым для идеи n-уровней, и продолжили знакомство с ним с помощью DI? — Кроме того, даже при этом вам это не понадобится. Просто создайте базовый класс контроллера, который обновит ваш уровень данных с помощью строки подключения — тогда у вас будет единая единица работы и единое место, где устанавливается строка. там нет необходимости в DI… Просто причина использовать DI ради использования DI.

4. DI может использоваться как для уровня служб, так и для уровня данных. Это обеспечивает единое местоположение для инициализации классов с помощью строк подключения, кодов API, конструкции ведения журнала, других статических значений и т. Д. Это лучшая привычка для разработки, и она упрощает последующее расширение отдельных классов, а не наследование от базового класса. DI также упрощает макет отдельных компонентов для модульных и интеграционных тестов. Я не говорю, что в вашем ответе что-то не так, я просто удивлен, что вы не упомянули DI как архитектурный вариант, учитывая, что у него много преимуществ.

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

Ответ №2:

Если вы поместите свои строки подключения в web.config, вы можете использовать ConfigurationManager.Строки подключения:

 var connectionString = ConfigurationManager
    .ConnectionStrings["ConnectionName"].ConnectionString;
 

MSDN

Комментарии:

1. В веб-формах я обычно обрабатываю одно подключение к базе данных с помощью ConfigurationManager и вытягиваю ключ, но в этом случае у меня много баз данных, подключенных к одному клиенту, поэтому я хотел что-то немного другое. Спасибо за ответ!

2. Если вы хотите пойти правильным путем, следуйте ответу @Darren (он называется n-layer, если вы хотите разобраться в нем). Если вы не зайдете так далеко, я бы все равно попросил ваш метод вернуть строку подключения из web.config. Кажется странным не делать этого из web.config.

3. Я думаю, что вы правы, или, скорее, я думаю, что согласен с вами. Единственное, что требует гибкости, — это начальный каталог после его подключения, поэтому само собой разумеется, что я могу сохранить остальную часть строки в web.config и просто привязать начальную часть каталога строки в методе. Мы будем очень признательны за ваши ответы!

Ответ №3:

В итоге я добавил общедоступный статический метод в файл WebApiConfig.cs. Этот метод принимает идентификатор и возвращает строку подключения. Там должен быть только один, так что это работает нормально. Я перехожу от этого, но если есть комментарии за или против этого метода, я бы хотел это услышать. Я изучаю этот материал прямо сейчас, и веб-API далек от веб-форм. Спасибо всем за ваше внимание!

    public static string getConnectionString()
    {
        return "the connection string";
    }
 

РЕДАКТИРОВАТЬ: после рассмотрения комментариев в других ответах я также добавил, что я собираюсь сохранить большую часть строки подключения в web.config и использовать только метод getConnectionString() для извлечения из ConfigurationManager и привязки к исходному каталогу, единственной изменяющейся части строки подключения. Спасибо всем за ваше внимание.

@Darren: Я также обязательно рассмотрю N-уровневую архитектуру, поскольку она выглядит как довольно стабильный способ справиться с этим, хотя я думаю, что на данный момент это выходит за рамки моих намерений. Спасибо всем за отличную информацию со всех сторон.

Комментарии:

1. Этот статический метод должен возвращать строку подключения из web.config предложенного @Smith. Не стоит жестко кодировать строку подключения внутри вашего кода на C #. Что делать, если имя сервера изменится? Будете ли вы обновлять этот статический метод, перестраивать и повторно развертывать свой код все, что происходит?

2. Это отличный момент. Единственное, что действительно нужно изменить, это начальный каталог, поэтому само собой разумеется, что все остальное должно храниться в web.config. Спасибо за ответ!