使用抽象泛型类时最小化依赖性要求

时间:2013-10-11 18:17:05

标签: c# generics inheritance dependencies

在我的数据访问层,它是它自己的库,我有一个POCO类,代表我的域对象的数据库表。我们可以使用一个例子,让它称之为MyClassDTO,即使有很多对象就像它一样。

在我的业务逻辑层中,它也在它自己的库中(并且引用了DAL库),它为每个对象提供了实际的Domain Object类。我们使用MyClass

BLL在其API中公开了一堆像MyClassBll这样的类,它们可以在Presentation项目中实例化,以获得对Domain逻辑和数据的访问。

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

Public Class MyClassBll : Bll<MyClass,MyClassDto>

这里的想法是BLL的作业采取域对象,这是表示层将要讲的语言,将它们变成DTO,这是DAL将要讲的语言,反之亦然。

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

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

我不希望我的演示文稿层必须知道我的DAL类。我怎样才能满足编译器的要求?有没有办法可以进一步隐藏我的DAL从Presentation层,同时仍然保持我当前设计的灵活性?

供参考,我的通用BLL类看起来像这样:

MyClassBll

}

这使得该类的通用实现看起来像这样:

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);
    }
}

1 个答案:

答案 0 :(得分:0)

  

我不想要我的演示层必须知道我的DAL   类。我怎样才能满足编译器的要求?我有办法吗?   进一步隐藏我的DAL从表示层,同时仍然保持   我当前设计的灵活性?

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

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

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

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