Создайте ConnectionStringProvider класс, который предоставит вам строку подключения
public class ConnectionStringProvider
{
// store it statically so that every instance of connectionstringprovider
// uses the same value
private static string _customerConnectionString;
public string GetCustomerConnectionString()
{
return _customerConnectionString;
}
public void SetCustomerConnectionString(string connectionString)
{
_customerConnectionString = connectionString;
}
}
Использование ConnectionStringProvider в вашем DAL
public class MyCustomerDAL
{
private ConnectionStringProvider _connectionStringProvider;
public MyCustomerDAL()
{
_connectionStringProvider = new ConnectionStringProvider();
}
public void UpdateSomeData(object data)
{
using (var con = new SqlConnection(
connectionString: _connectionStringProvider.GetCustomerConnectionString()))
{
//do something awesome with the connection and data
}
}
}
Установка / изменение строки подключения
new ConnectionStringProvider()
.SetCustomerConnectionString(connString);
Примечание
Причина, по которой я решил использовать метод вместо свойства get / set в ConnectionStringProvider, заключается в том, что, возможно, в будущем вы решите читать / записывать их из файла, и хотя вы можете читать / писать из файла в свойстве, которое вводит в заблуждение вашего потребителя. кто думает, что свойство будет простым хитом без производительности.
Использование функции говорит вашему потребителю о возможном падении производительности, поэтому используйте ее с умом.
Небольшая абстракция для юнит-тестирования
Вот небольшой вариант, который позволит вам абстрагироваться для модульного тестирования (и в конечном итоге IoC)
public class MyCustomerDAL
{
private IConnectionStringProvider _connectionStringProvider;
public MyCustomerDAL()
{
//since not using IoC, here you have to explicitly new it up
_connectionStringProvider = new ConnectionStringProvider();
}
//i know you don't want constructor, i included this to demonstrate how you'd override for writing tests
public MyCustomerDAL(IConnectionStringProvider connectionStringProvider)
{
_connectionStringProvider = connectionStringProvider;
}
public void UpdateSomeData(object data)
{
using (var con = new SqlConnection(
connectionString: _connectionStringProvider.GetCustomerConnectionString()))
{
//do something awesome with the connection and data
}
}
}
// this interface lives either in a separate abstraction/contracts library
// or it could live inside of you DAL library
public interface IConnectionStringProvider
{
string GetCustomerConnectionString();
void SetCustomerConnectionString(string connectionString);
}
public class ConnectionStringProvider : IConnectionStringProvider
{
// store it statically so that every instance of connectionstringprovider uses the same value
private static string _customerConnectionString;
public string GetCustomerConnectionString()
{
return _customerConnectionString;
}
public void SetCustomerConnectionString(string connectionString)
{
_customerConnectionString = connectionString;
}
}
Приложение A - Использование IoC и DI
Отказ от ответственности: цель следующей части о IoC не в том, чтобы сказать, что один путь является правильным или неправильным, а просто в том, чтобы выдвинуть идею как другой способ решения проблемы.
В этой конкретной ситуации внедрение зависимостей сделает решение задачи очень простым; особенно если вы использовали контейнер IoC в сочетании с инжектором конструктора.
Я не имею в виду, что это сделало бы код более простым, оно было бы более или менее одинаковым, это сделало бы умственную сторону "как мне легко получить некоторую услугу в каждом классе DAL?" простой ответ; введите его .
Я знаю, что вы сказали, что не хотите менять конструктор. Это круто, вы не хотите менять это, потому что это - боль - поменять все места реализации.
Однако, если бы все создавалось IoC, вы бы не заботились о добавлении в конструкторы, потому что никогда не вызывали бы их напрямую.
Затем вы можете добавить такие службы, как ваш новый IConnectionStringProvider, прямо в конструктор и покончить с этим.