在模块化架构中制作数据访问层的正确方法是什么?

时间:2019-06-04 19:46:02

标签: c# architecture data-access-layer

我正在用C#编写模块化应用程序。我有“核心”,分为几层,例如:DAL,BLL和Presentation层。所以主要的问题是关于我的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只有两种方法。但是我需要像“ GetBandsThatCreatedAt(int year)”这样的方法。 IBandsDAO没有此方法。在我的模块中,我想要做

 // IBandsRaitingModuleData moduleDbData;

 ICollection<Band> bands = moduleDbData.Bands.GetBandsByPersonsInBand(7);
 ICollection<Band> bands = moduleDbData.Bands.GetBandsThatCreatedAt(7);

因此,我希望能够将BandsRaitingModuleData用作IDBData,同时使用其他方法。

哪种方法是最好的方法?

1 个答案:

答案 0 :(得分:0)

您将不得不对较窄的接口进行一些强制转换以获得更细粒度的功能。因此,使用较窄的方法创建IBandsDAO接口,并使其扩展您的IDBData接口。这将需要向下转换到较窄的接口,但不会迫使您进入特定的提供程序接口,因此仍保留您的封装。