Пишу модульное приложение на C #. У меня есть «ядро», которое разделено на слои, например: DAL, BLL и уровень представления. Итак, главный вопрос касается моего DAL.
В моем приложении я хочу иметь возможность переключить базу данных. Из-за этого в моем DAL есть 2 папки: Mysql и Postgresql.
У меня есть таблицы: Персоны, Группы, Песни и т. Д. (15 таблиц).
Чтобы все эти таблицы были в одном месте, я создал класс DBData.
public interface IDBData
{
IPersonsDAO Persons {get;}
IBandsDAO Bands {get;}
...
}
public interface IBandsDAO
{
ICollection<Band> GetBandsByPersonsInBand(int personsCount);
ICollection<Band> GetAll();
}
Итак, например, в DAL / Postgresql у меня есть
public class PostgresqlDbData : IDBData
{
IConnectionFactory _connectionFactory
//tables
PostresqlPersonsDao _persons;
PostresqlBandsDao _bands;
PostgresqlDbData (IConnectionFactory connectionFactory)
{
_connectionFactory = _connectionFactory;
}
IPersonsDAO Persons get { return _persons ?? (_persons = new PostresqlPersonsDao (_connectionFactory)); }
IBandsDAO Bands get { return _bands?? (_bands = new PostresqlBandsDao (_connectionFactory)); }
...
}
Таким образом, я могу легко получить любой класс таблицы dao в своем коде, например:
IDBData dbData = new PostgresqlDbData (connectionFactory);
ICollection<Person> persons = dbData.Persons.GetSingers();
ICollection<Band> bands = dbData.Bands.GetBandsByPersonsInBand(7);
...
Почему мне это понравилось?
Поскольку я использую внедрение зависимостей, и мне больше не нужно вводить все таблицы, которые мне нужны в конструкторе класса, но я могу просто получить их все, получив экземпляр только IDBData.
///Some class that uses my IdbData
public class OrderService
{
IDBData _dbData
ShopService(IDBData dbData)
{
_dbData = dbData;
}
public void OrderAlbum(string albumName, string bandName)
{
...
IAlbum album = _dbData.Albums.GetAlbum(albumName, bandName);
..
}
public void OtherMethod(string personName)
{
...
_dbData.Persons.GetPerson(personName);
..
}
}
Как вы можете видеть в моей службе OrderService, я использую _dbData. И это введено в конструктор.
Да, возможно, это похоже на Service Locator, но я не могу найти другого способа сделать это лучше. Если бы я этого не делал, мне нужно было бы внедрить каждый класс таблицы в методы.
Как я уже сказал, у меня есть модульное приложение. Таким образом, каждый модуль независим, но он знает ядро. При инициализации модуля он получает экземпляр IDBData.
Например, у меня есть модуль BandsRaitingModule.
Это основная проблема.
IBandsDAO имеет всего 2 метода. Но мне нужен метод типа GetBandsThatCreatedAt (int year). IBandsDAO не имеет этого метода. В моем модуле я хочу сделать как
// IBandsRaitingModuleData moduleDbData;
ICollection<Band> bands = moduleDbData.Bands.GetBandsByPersonsInBand(7);
ICollection<Band> bands = moduleDbData.Bands.GetBandsThatCreatedAt(7);
Поэтому я хочу иметь возможность использовать мои BandsRaitingModuleData как IDBData и в то же время использовать другие методы.
Как лучше всего этого достичь?