我正在尝试使用ado.net和sql server设计应用程序体系结构。我考虑使用以下三维图层:
表示层->业务层(BAL)->数据访问层(DAL)
员工,部门等示例对象的实体。
我正在尝试将接口用作某些类的合同。我当前的问题是,我看到BAL和DAL对象之间共有一些方法,例如:Add,Remove,GetAll,因此我决定创建接口来实现此类操作,但是从BAL类使用时,我需要像{{1 }},但在DAL void Add(Employee)
中,因此我在DAL和BAL上拆分了几乎相同的接口(我不喜欢它,因为它似乎以某种方式重复了)。下一个问题是,当我想在void Add(string name);
上使用我的代码时,例如我无法调用StickTogether class
,这是因为_employee.Department = _department;
应该在Department property
界面中,但是很简单实体RepositoryBal
需要实现我不想做的接口,因为据我所知,实体只是对特定对象的简单表示。您能否告诉我-最好的例子来说明您如何创建这样的体系结构或修改我的体系以拥有比我现在更好的东西。下面找到我正在处理的完整代码。如何解决?
请注意,我也开始准备此代码以进行依赖,这将对MOC测试有所帮助。
使用根据我的代码提出的固定解决方案来欣赏您的答案。
Department
答案 0 :(得分:2)
3层(anti pattern?)在这里是红色鲱鱼,实际上是在讲dependency injection.模式。这些变得难以手动管理。我建议您实现一个Simple Injector或Unity这样的DI框架。
我正在尝试将接口用作某些类的合同。
为什么有些课程?如果要实施依赖项注入,请在所有类上实现它。
我当前的问题是,我发现某些方法在 BAL和DAL对象,例如:Add,Remove,GetAll,因此我决定 创建实现此类事情的接口
这是您的第一个错误。您已经根据功能而不是责任进行了分解。仅仅因为某些事物具有相似的方法签名并不意味着它们应该相关。客户业务对象与客户数据对象负有完全不同的责任。记住favour composition over inheritance。
但是当从BAL类中使用时,我需要像void那样使用它 Add(雇员),但在DAL中无效Add(字符串名称);
这只是强调了上述内容,您已经做出决定,因为方法被称为“添加”,它们的名称相同,而显然不同。
我想说您应该为每个对象实现一个接口 ,不要尝试关联不相关的对象,然后使用DI框架对其进行配置,然后注入它们。尽量不要使线条模糊并保持分隔清晰。记住您要high cohesion and low coupling.
举一些例子,我会完全忘记您的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框架完成,而所有依赖关系都将解耦。