通用 DAL / BLL 类

Posted

技术标签:

【中文标题】通用 DAL / BLL 类【英文标题】:Generic DAL / BLL Classes 【发布时间】:2013-02-06 21:35:11 【问题描述】:

我目前正在为我们的新应用程序构建数据访问层和业务逻辑层类,我有一个问题(显然)。首先,这里有一些可能会有所帮助的细节:

使用 Entity Framework 5 进行模型类和数据访问 每个“层”在不同的类库和命名空间(即 App.Model、App.DAL、App.BLL)中分开

从 DAL 开始 - 我决定为所有 DAL 类编写一个基类来继承。

public abstract class DALBase<T> : IDisposable

    protected AppEntities context;
    protected DbSet set;

    public DALBase()
    
        context = new OECCORPEntities();
        set = context.Set(typeof(T));
    

    protected virtual void Save()
    
        context.SaveChanges();
    

    public virtual void Add(T model)
    
        set.Add(model);
        Save();
    

    public virtual T Get(int id)
    
        return (T)set.Find(id);
    

    public virtual List<T> GetAll()
    
        return set.OfType<T>().ToList();
    

    public virtual void Delete(int id)
    
        T obj = Get(id);
        set.Remove(obj);
        Save();
    

    public virtual void Update()
    
        Save();
    

    public void Dispose()
    
        context.Dispose();
    

正如您将看到的,基类实现了一个泛型类型,它应该是 DAL 类负责使用的模型的类型。使用泛型类型,在构造函数中,它使用泛型参数的类型创建一个 DbSet - 在下面预定义的类似 CRUD 的虚函数中使用(添加、获取等)。

然后我明白了——等一下……因为它是通用的,我真的不必为每个模型都实现 DAL 类。我可以这样写:

public class GenericDAL<T> : DALBase<T>

    public GenericDAL() : base() 

...我可以用于任何模型。好的,等等到业务逻辑层。我也为 BLL 创建了一个基类:

public abstract class BLLBase<T>

    protected GenericDAL<T> dal;

    public BLLBase()
    
        dal = new GenericDAL<T>();
    

    public virtual void Add(T model)
    
        dal.Add(model);
    

    public virtual T Get(int id)
    
        return dal.Get(id);
    

    public virtual List<T> GetAll()
    
        return dal.GetAll();
    

    public virtual void Delete(int id)
    
        dal.Delete(id);
    

    public virtual void Update()
    
        dal.Update();
    

... 它使用 GenericDAL 来完成它的工作。所以以一种类似的方式,我只是编写了一个 GenericBLL 类,如下所示:

public class GenericBLL<T> : BLLBase<T>

    public GenericBLL() : base()  

为了测试它,一个简单的控制台应用程序:

class Program

    static void Main(string[] args)
    
        GenericBLL<ADMIN> bll = new GenericBLL<ADMIN>();
        List<ADMIN> admins = bll.GetAll();
    

... 其中“ADMIN”是模型类型。像魅力一样工作。

这背后的想法是避免必须为每个模型编写 DAL / BLL 类,除非它需要额外的功能。有人能告诉我为什么我不会想这样做吗?我认为可以完成工作并节省开发时间。

感谢您的宝贵时间。

【问题讨论】:

【参考方案1】:

嗯,一个缺点是,如果您决定稍后添加一些业务规则,则必须将类型从 GenericBLL[Whatever] 切换到 WhateverBLL

一个明显的解决方案是创建一个继承自 GenericBLL[Whatever] 的类。喜欢:

public class WhateverBLL : GenericBLL<Whatever>

改用这个类。

【讨论】:

对。如果一个模型需要更多的标准 crud 功能,我会为它实现一个特定的 BLL 类。 “模型”所需的许多功能都是非常基本的。所以泛型类会提供很多服务。 我建议您从一开始就为所有实体编写特定的 BLL 类。它们只需要是从您的通用基类继承的存根即可。通过这样做,如果您决定稍后添加一些业务逻辑,您将不必更改您的类型。 很好的建议 - 很有意义。谢谢!【参考方案2】:

目前,您的 BLL 并没有特别增加价值。每个调用都只是传递到另一层。也许是您的应用程序的简单性(感谢您的幸运星,您是如此幸运),或者也许您拥有我将其归类为生活在其他地方的实际业务逻辑。

对我来说,业务逻辑是在持久化数据之前完成的所有事情,在检索数据之后完成的所有事情,以及类似的事情。决定,道路上的岔路口,所采取的行动。相比之下,实际上保存和检索数据通常是极其微不足道的。

所以当我查看您的通用 DAL 基类时,我认为这是一个好的开始。我可能会从中提取一个接口,以便在测试时替换它。目前,继承基类的类没有增加任何价值。不要仅仅为了它而创建图层和类,确保它可以增加价值并以某种方式让您的生活更轻松。

当我查看您的通用 BLL 类时,我认为您可能将真正的业务逻辑隐藏在某种形式的代码隐藏中,或者隐藏在控制台应用程序的类文件中。虽然肯定有可能存在仅因类型而异的通用功能,但我不认为 one class 是您想要的。我的建议是重新考虑您认为的实际业务逻辑。到 DAL 的简单传递层可能不是。

【讨论】:

目前还没有真正实现任何实际的业务逻辑。这是该项目的开始。因为我熟悉这种模式,所以使用 BLL 的应用程序不应该知道 DAL。因此,基本的 crud 功能只是此时所需的最低限度。当需要添加新的业务逻辑时,我编写一个特定于具有所需功能的模型的 BLL 类。我的想法是我只需要在需要时编写那些特定的类,而不是为每个单独的类。我们需要的很多东西对于某些模型来说确实是基本的。

以上是关于通用 DAL / BLL 类的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET MVC:BLL 和 DAL 到存储库设计

如何在 UI、BLL、DAL 之间使用 DTO

EF框架

DAL 和 BLL 应通过的类型

BLL,DAL,BO,插入数据

延迟加载的 DAL 和 BLL