1

在我的数据访问层(它自己的库)中,我有一个 POCO 类,它代表我的域对象的数据库表。我们可以以一个为例,我们称它为MyClassDTO,即使有几十个像它一样的对象。

在我的业务逻辑层中,它也在它自己的库中(并且引用了 DAL 库),它具有每个对象的实际域对象类。让我们使用MyClass.

BLL 作为其 API 公开了一堆类MyClassBll,例如 ,可以在 Presentation 项目中实例化这些类,以便访问域逻辑和数据。

为了让我的生活更轻松,大多数 BLL 对象MyClassBll都继承自通用抽象Bll<TModel,TDto>类。因此,例如MyClassBll声明如下:

Public Class MyClassBll : Bll<MyClass,MyClassDto>

这里的想法是 BLL 的任务是获取域对象,这是表示层将要使用的语言,将它们转换为 DTO,这是 DAL 将要使用的语言,反之亦然。

它确实使创建各种对象变得轻而易举,特别是因为我可以在需要时覆盖通用实现,而在它简单的时候就不用管它了。到现在为止还挺好。

当我开始在我的演示文稿中使用它时,我才遇到了一个问题。我将 BLL 库作为参考包含在内,但它不允许我使用任何方法,MyClassBLL,因为它不知道 的定义,因为它的定义MyClassDto在元数据中MyClassBll

我不想让我的表示层知道我的 DAL 类。我怎样才能满足编译器?有没有一种方法可以进一步从表示层隐藏我的 DAL,同时仍然保持我当前设计的灵活性?

作为参考,我的通用 BLL 类如下所示:

public abstract class Bll<TModel, TDto> : IBll<TModel, TDto>
    where TModel : class
    where TDto : class
{
    protected User User;

    protected static string[] AdminGroups;

    protected bool IsAdmin;

    protected static Func<UnitOfWork, GenericRepository<TDto>> Repository;

    private void AdminCheck()
    {
        if (!IsAdmin)
        {
            throw new SecurityException("That Action Requires Admin Privileges");
        }
    }

    public Bll(User user)
    {
        StaticMapBulder.initialize();
        if (User == null)
        {
            throw new ArgumentNullException("User Can not be null");
        }
        user = User;
        IsAdmin = false;
        foreach (var AdminGroup in AdminGroups)
        {
            if (user.IsInGroup(AdminGroup))
                {
                    IsAdmin = true;
                }
        }
    }

    public virtual TModel Insert(TModel ItemToAdd)
    {
        AdminCheck();
        using (var uow = new  UnitOfWork())
        {
            var OutgoingDto = MapModelToDto(ItemToAdd);
            var InboundDto = Repository(uow).Insert(OutgoingDto);
            uow.Save();
            return MapDtoToModel(InboundDto);

        }

    }

    public virtual List<TModel> GetAll()
    {
        using (var uow = new UnitOfWork())
        {
            var InboundDto = Repository(uow).Get();
            var ModelList = new List<TModel>();
            foreach (var item in InboundDto)
            {
                ModelList.Add(MapDtoToModel(item));
            }
            return ModelList;
        }

    }

    public virtual TModel GetByID(int ID)
    {
        using (var uow = new UnitOfWork())
        {
            var InboundDto = Repository(uow).GetByID(ID);
            return MapDtoToModel(InboundDto);
        }
    }

    public virtual void Update(TModel ItemToUpdate)
    {
        AdminCheck();
        using (var uow = new UnitOfWork())
        {
            var OutboundDto = MapModelToDto(ItemToUpdate);
            Repository(uow).Update(OutboundDto);
            uow.Save();
        }
    }

    public virtual void Delete(TModel ItemToDelete)
    {
        using (var uow = new UnitOfWork())
        {
            var OutboundDto = MapModelToDto(ItemToDelete);
            Repository(uow).Delete(OutboundDto);
            uow.Save();
        }
    }

    public virtual void DeleteByID(int ID)
    {
        using (var uow = new UnitOfWork())
        {
            Repository(uow).Delete(ID);
            uow.Save();
        }
    }


    virtual public TModel MapDtoToModel(TDto Dto)
    {
        return Mapper.Map<TModel>(Dto);
    }

    virtual public TDto MapModelToDto(TModel Model)
    {
        return Mapper.Map<TDto>(Model);
    }
}

}

这使得该类的通用实现如下所示:

public class MyClassBll : Bll<MyClass, MyClassDto>
{
    public MyClassBll(User user)
        : base(user)
    {

    }

    new protected static Func<UnitOfWork, GenericRepository<MyClassDto>> Repository = x => x.MyClassRepository;
    new protected static string[] AdminGroups = { "MyClassAdministrators" };
}
4

1 回答 1

0

我不想让我的表示层知道我的 DAL 类。我怎样才能满足编译器?有没有一种方法可以进一步从表示层隐藏我的 DAL,同时仍然保持我当前设计的灵活性?

这不是您需要满足的编译器,而是您的设计要求。

为什么不想让演示文稿了解 DTO?DTO 的职责是在组件之间传递。使用 DTO 将数据从业务类传递到演示文稿是完全可以接受的。

您想从演示文稿中隐藏 DAL 是正确的。您需要更改您的设计以启用此功能。

我推荐一个依赖于你的 DAL 的存储库。此存储库是唯一依赖于 DAL 的组件。现在,您的业务类可以在您的存储库上调用 CRUD 操作。您的业​​务类对存储库返回的数据执行一些转换和计算。如果您需要更新您的演示文稿,请将您现在转换的数据的模型或 DTO 发送给它。关注点是分开的。

于 2013-10-11T18:52:14.887 回答