【问题标题】:Correct way to make data access layer in modular architecture?在模块化架构中制作数据访问层的正确方法?
【发布时间】:2019-10-20 08:49:16
【问题描述】:

我正在用 C# 编写模块化应用程序。我有“核心”,它分为多个层,例如:DAL、BLL 和表示层。所以主要问题是关于我的 DAL。

在我的应用程序中,我希望有机会切换数据库。因此,在我的 DAL 中,我有 2 个文件夹:Mysql 和 Postgresql。

我有表格:Persons、Bands、Songs 等(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。并注入到构造函数中。

是的,也许它看起来像服务定位器,但我找不到其他方法让它变得更好。如果我不这样做,我需要在方法中注入每个表类。

就像我说的,我有一个模块化应用程序。所以每个模块都是独立的,但它知道核心。当模块初始化时,它会获取 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 并同时使用其他方法。

到达那里的最佳方式是什么?

【问题讨论】:

  • 你的问题有点混乱。也许您可以重新阅读您的要求并更好地表达它?
  • 好的,简短的回答 - 如何组织我的数据访问层以使其对所有模块通用,但同时每个模块都有机会添加特定的功能(我的意思是 DAL 的方法)。

标签: c# architecture data-access-layer


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 2015-06-17
    • 1970-01-01
    • 2018-08-24
    • 1970-01-01
    • 2016-04-16
    • 2013-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多