分层实体或共享实体之间的混合架构方法

本文关键字:实体 方法 混合 之间 共享 分层 | 更新日期: 2023-09-27 18:22:08

我们正在开发一个具有以下层的应用程序:

  • UI
  • 业务层(BL)
  • 数据层(DL):包含通用CRUD查询和自定义查询
  • 物理数据层(PDL):例如实体框架

我们正在寻找一种将物理数据层的实体共享到DL和BL的方法。

在决定最佳架构时,以下几点很重要:

  • 可重用性:数据库字段应该尽可能容易地迁移到其他层
  • 快速实现:向数据库中添加字段不应导致在所有层之间映射实体
  • 可扩展性:BL实体可以使用特定于BL的属性进行扩展(DL实体也是如此)

我遇到过为所有层共享实体的体系结构(+快速实现,-可扩展性),或者每层共享一个实体(DTO)的体系结构,(+可扩展性,-快速实现/可重用性)。这篇博客文章描述了这两种体系结构。

有没有一种方法将这些体系结构结合起来,并将我们的需求考虑在内?

目前,我们已经提出了以下类和接口:

接口:

// Contains properties shared for all entities
public interface I_DL
{
    bool Active { get; set; }
}
// Contains properties specific for a customer
public interface I_DL_Customer : I_DL
{
    string Name { get; set; }
}

PDL-

// Generated by EF or mocking object
public partial class Customer
{
    public bool Active { get; set; }
    public string Name { get; set; }
}

DL-

// Extend the generated entity with custom behaviour
public partial class Customer : I_DL_Customer
{
}

BL-

// Store a reference to the DL entity and define the properties shared for all entities
public abstract class BL_Entity<T> where T : I_DL
{
    private T _entity;
    public BL_Entity(T entity)
    {
        _entity = entity;
    }
    protected T entity
    {
        get { return _entity; }
        set { _entity = value; }
    }
    public bool Active
    {
        get
        {
            return entity.Active;
        }
        set
        {
            entity.Active = value;
        }
    }
}
// The BL customer maps directly to the DL customer
public class BL_Customer : BL_Entity<I_DL_Customer>
{
    public BL_Customer (I_DL_Customer o) : base(o) { }
    public string Name
    {
        get
        {
            return entity.Name;
        }
        set
        {
            entity.Name = value;
        }
    }
}

分层实体或共享实体之间的混合架构方法

每层DTO设计是最灵活和模块化的。因此,它也是最可重用的:不要混淆重用相同实体的便利性和不同模块的可重用性,这是架构级别的主要问题。然而,正如您所指出的,如果您的实体经常发生变化,那么这种方法既不是开发最快的,也不是最敏捷的。

如果你想在层之间共享实体,我不会经历通过不同层指定层次结构的麻烦;我要么让所有层直接使用EF实体,要么在所有层共享的不同程序集中定义这些实体——包括物理数据层,它可以首先通过EF代码直接保持这些实体,或者将这些共享实体转换为EF实体。