为了账号安全,请及时绑定邮箱和手机立即绑定

三层架构方法和设计方法

三层架构方法和设计方法

C#
小唯快跑啊 2021-12-25 16:31:30
我正在尝试使用 ado.net 和 sql server 设计我的应用程序架构。我考虑使用以下三个层:表示层 -> 业务层 (BAL) -> 数据访问层 (DAL)示例对象的实体,如员工、部门等。我正在尝试使用接口作为我的一些类的契约。我目前的问题是,我看到一些方法在 BAL 和 DAL 对象之间是通用的,例如:Add、Remove、GetAll 因此我决定创建接口来实现这些东西但是当从 BAL 类使用时我需要像void Add(Employee)但在 DAL 中void Add(string name);因此我在 DAL 和 BAL 上拆分了几乎相同的接口(我不喜欢它,因为它似乎以某种方式重复了)。下一个问题是当我想在StickTogether class我无法调用时 使用我的代码时,_employee.Department = _department;我知道这是因为Department property应该在RepositoryBal接口中,但在简单实体中Department需要实现我不想做的这样的接口,因为就我而言,实体只是特定对象的简单重复。你能告诉我 - 最好的例子展示你将如何创建这样的架构或修改我的东西以拥有比我现在更好的东西。下面找到我正在处理的完整代码。如何解决这个问题?请注意,我也开始为依赖准备此代码,这将有助于 moc 测试。使用基于我的代码提出的固定解决方案感谢您的回答。
查看完整描述

1 回答

?
呼如林

TA贡献1798条经验 获得超3个赞

3 层(反模式?)在这里是一个红鲱鱼,你本质上是在谈论依赖注入。图案。这些变得难以手动管理。我建议你实现一个像Simple Injector或 Unity这样的 DI 框架。


我正在尝试使用接口作为我的一些类的契约。


为什么有些课程?如果您要实现依赖注入,则在所有类上实现它。


我目前的问题是我看到一些方法在 BAL 和 DAL 对象之间是通用的,例如:Add、Remove、GetAll 因此我决定创建接口来实现这些东西


这是你的第一个错误。您已经根据功能而不是责任进行了分解。仅仅因为某些东西具有相似的方法签名并不意味着它们应该相关。客户业务对象与客户数据对象的职责非常不同。记住优先组合胜过继承。


但是当从 BAL 类使用时,我需要像 void Add(Employee) 但在 DAL void Add(string name);


这只是突出了上述内容,您已经做出决定,因为这些方法被称为“添加”,因此它们显然不是。


我会说你应该为每个对象实现一个接口,不要尝试关联不相关的对象,然后使用 DI 框架配置它,然后注入它们。尽量不要模糊您的线条并保持您的分隔清晰。请记住,您需要高内聚和低耦合。


举一些例子,我会IRepositoryBal完全忘记你和泛型,只是简化整个事情:


//your going to struggle to do DI with internal classes, make them public

public class EmployeeBal : IEmployeeBal

{

   //


public interface IEmployeeBal

{

    void Add(Employee entity);

    void Delete(Employee entity);

    IEnumerable<Employee> GetAll();

    Department Department {get; set;}

}


public class StickTogether

{

    private readonly IEmployeeBal _employee;

    private readonly IDepartmentBal _department;


    public StickTogether(IEmployeeBal  employee, IDepartmentBal  department)

    {

        _employee = employee;

        _department = department;

    }


    public void Create()

    {

        _employee.Add(new Employee());

        _department.Add(new Department());

        _employee.Department = _department; //not accessible which has a sense

    }

}

然后,您可以在 DI 框架中配置这些,例如在简单的 Injector 中,您将执行以下操作:


Container _defaultContainer = new Container();

_defaultContainer.Register<IEmployeeBal, EmployeeBal>();

_defaultContainer.Register<IDepartmentBal, DepartmentBal>();

_defaultContainer.Register<IDepartmentDal, DepartmentDal>();

 //..etc.

然后你得到你的父实例(仅!)因此:


IEmployeeBal entryPoint = _defaultContainer.GetInstance<IEmployeeBal>();

DI 框架会完成剩下的工作,并且您的所有依赖项都已解耦。


查看完整回答
反对 回复 2021-12-25
  • 1 回答
  • 0 关注
  • 150 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信