简体   繁体   English

三层架构模式

[英]3-Layer Architecture Pattern

Is it OK to implement BLL and DAL using partial class this way: 这样可以使用部分类实现BLL和DAL吗:

 namespace BLL
{
   partial class Employee
  {
    public string EmpID { get; set; }
    public string EmpName { get; set; }

     public List<Employee> GetListOfEmployees()
     { 
       return DAL.Employee.GetListOfEmplyee();
      }

     }
  }

namespace DAL
{
 partial class Employee
 {
    public static List<Employee> GetListOfEmployees()
    {
        //DATA ACCESS
        var emps = GetEmployeesFromDb(); // fetch from db
        return emps;
   }
 }
}

or any other suggestions? 或其他建议? thanks in advance. 提前致谢。

It's unclear what you're trying to achieve by making your classes partial . 目前尚不清楚您要通过使类成为partial来实现什么。 Partial classes are useful when you need to split a single class across multiple files - usually because one or more portions are machine-generated. 当您需要将一个类拆分为多个文件时,部分类很有用-通常是因为一个或多个部分是机器生成的。 In this case, separating the machine-generated from human-edited portions is useful to avoid having one set of changes overwrite or break the other. 在这种情况下,将机器生成的部分与人工编辑的部分分开是非常有用的,可以避免一组更改覆盖或破坏另一组更改。

In you example, using partial doesn't achieve much, since the two Employee classes are in different namespaces - they will not be merged into a single implementation. 在您的示例中,使用partial并不会取得太大效果,因为两个Employee类位于不同的命名空间中-它们不会合并到单个实现中。

Perhaps if you can explain the problem you are trying to solve, you may be able to get a better answer to your question. 也许,如果您可以解释您要解决的问题,则可能会更好地回答您的问题。

A lot comes down to preference, but personally, I would create a Factory class for Employee/EmployeeCollection creation and not put it in the object itself. 很大程度上取决于偏好,但是就个人而言,我会为Employee / EmployeeCollection创建创建Factory类,而不是将其放在对象本身中。 If i did put it in the object, I would make the object creation methods static so you don't have to instantiate a dummy object just to create real objects. 如果确实将它放在对象中,则可以使对象创建方法静态化,因此您不必实例化虚拟对象即可创建真实对象。

In the past, I've built the creation logic, including the DAL calls, into the actual constructor (using dependency injection to get the data configurations into the object). 过去,我已经将创建逻辑(包括DAL调用)构建到了实际的构造函数中(使用依赖注入将数据配置放入对象中)。 In this case, the constructors take things like Id or Name -- something you use to identify the object. 在这种情况下,构造函数采用IdName东西-用于标识对象的东西。 It passes this down to the DAL and builds the object based on the result set. 它将其传递给DAL,并根据结果集构建对象。

You can't use partial classes that way - BLL.Employee is a different class than DAL.Employee because they are in different namespaces. 您不能以这种方式使用部分类-BLL.Employee与DAL.Employee是不同的类,因为它们位于不同的命名空间中。 You'll just have 2 partial classes with no other parts. 您将只有2个局部类,而没有其他部分。

Even if they did represent the same class, they can't both define a method with the same signature. 即使它们确实表示相同的类,也不能同时定义具有相同签名的方法。

Please correct me if I am wrong but by creating a partial Employee class in two different namespaces (DAL and BLL) you simply create two different classes. 如果我错了,请纠正我,但是通过在两个不同的命名空间(DAL和BLL)中创建部分Employee类,您只需创建两个不同的类。 It looks like you want to create a single class that consists of two partial classes - which is not the case in your example. 看起来您想创建一个包含两个部分类的单个类-在您的示例中情况并非如此。 In your code example you can simply remove the partial identifier. 在您的代码示例中,您可以简单地删除部分标识符。

Apart from that it is a good way in my opinion to split business logic from user interface and data access. 除此之外,我认为这是从用户界面和数据访问中分离业务逻辑的好方法。 So either by using three assemblies or simply three folders in the same Visual Studio project. 因此,可以在同一Visual Studio项目中使用三个程序集或仅使用三个文件夹。 It always depends in the end on how complex your solution is. 最终,最终取决于解决方案的复杂程度。

Especially when using LINQ to SQL or Entities I find it good practice to keep as much LINQ code in the data access layer. 特别是当使用LINQ to SQL或Entities时,我发现在数据访问层中保留尽可能多的LINQ代码是一种很好的做法。 This will make the code more re-usable and testable. 这将使代码更加可重用和可测试。

Everyone else is correct that this creates two separate classes. 每个其他人都是正确的,因为这会创建两个单独的类。 To not create two separate classes and separate your data from logic through partial classes, you could have the following two files in your project: 为了不创建两个单独的类并通过局部类将数据与逻辑分开,您的项目中可以包含以下两个文件:

  • Employee.cs Employee.cs
  • Employee.bl.cs Employee.bl.cs

Then your Employee.cs code would look like this: 然后,您的Employee.cs代码将如下所示:

namespace YourNamespace
{
    partial class Employee
    {
        public string EmpID { get; set; }
        public string EmpName { get; set; }
    }
}

And Employee.bl.cs would look like this: Employee.bl.cs看起来像这样:

namespace YourNamespace
{
    partial class Employee
    {
        public static List<Employee> GetListOfEmployees()
        {
            //DATA ACCESS
            var emps = GetEmployeesFromDb(); // fetch from db
            return emps;
        }
    }        
}

Though I would think that having a Repository class for retrieving data would be more appropriate than having GetListOfEmployees inside of Employee . 尽管我认为拥有一个用于检索数据的Repository GetListOfEmployeesEmployee内部拥有GetListOfEmployees更合适。

Update: 更新:

When I say repository, I'm referring to the Repository design pattern . 当我说存储库时,我指的是“ 存储库设计模式” A repository is an interface for retrieving and storing objects (from a relational database, for example). 存储库是用于检索和存储对象的接口(例如,从关系数据库中)。 If you are using an ORM like LINQ to SQL or the ADO.NET Entity Framework, they typically auto-generated classes that fill this role. 如果您使用的是诸如LINQ to SQL或ADO.NET实体框架之类的ORM,它们通常会自动生成充当该角色的类。 If, however, if you writing your own database access code, you could create your own repository class like this: 但是,如果您编写自己的数据库访问代码,则可以这样创建自己的存储库类:

public class Repository
{
    public Repository(string connectionString)
    {
        // ...
    }

    public IEnumerable<Employee> GetEmployees()
    {
        return GetEmployeesFromDb();
    }

    public Employee GetEmployeeById(Guid id)
    {
        // ...
    }

    public void StoreEmployee(Employee employee)
    {
        // ...
    }

    // etc.
}

The benefit of this is that you don't have to place database code throughout your Employee class or any of the other persistent classes. 这样做的好处是您不必在整个Employee类或任何其他持久性类中放置数据库代码。 All of the database access is done through one interface. 所有数据库访问都是通过一个界面完成的。 You could also create an interface and have multiple implementations of the repository; 您还可以创建一个interface并具有存储库的多个实现。 that way, you could have a way to store Employee instances in a file, for example, without having to change the Employee class. 这样,您可以将Employee实例存储在文件中,例如,而不必更改Employee类。

(1) Put your business objects/table entities in a shared particular place. (1)将您的业务对象/表实体放在共享的特定位置。 Suppose you have these classes: Employee(may refer to one row in table Employees), Department(may refer to one row in table Departments) and etc. These classes are probably used in all your layers. 假设您具有以下类:Employee(可能引用表Employees中的一行),Department(可能引用表Departments中的一行)等等。这些类可能在您的所有层中使用。 So put them in a shared place with well-named folders. 因此,请将它们放在带有命名文件夹的共享位置。

(2) Don't put business logics/data logics in entities. (2)不要将业务逻辑/数据逻辑放在实体中。 You see you put GetListOfEmployees in Employee . 您会看到将GetListOfEmployees放入Employee But in fact there is little relationship between them. 但是实际上它们之间几乎没有关系。 There should be a class called EmployeeManager, in which there are actions on employees such as find,update and delete. 应该有一个名为EmployeeManager的类,其中有对员工的操作,例如查找,更新和删除。

(3) See GetListOfEmployees method in both BLL and DAL, they are totally the same! (3)请参阅BLL和DAL中的GetListOfEmployees方法,它们完全相同! But the method in BLL is supposed to contain "Business Logics", that is why we call it BL-Layer. 但是BLL中的方法应该包含“业务逻辑”,因此我们将其称为BL-Layer。 In BLL methods' names are considered to be "business words", eg in the method it tells the DAL "I need all the employees, order by name". 在BLL方法中,名称被认为是“商务词汇”,例如,在方法中,它告诉DAL“我需要所有员工,按名称排序”。 BLL tells "what I need" and DAL do the picking. BLL告诉“我需要什么”,DAL进行挑选。 Methods in DAL have no business things. DAL中的方法没有任何事务。

One thing that might be escaping the OP is that namespaces are just a fanciful way of performing name-mangling of a sort. 可能会逃避OP的一件事是,名称空间只是执行某种名称处理的一种幻想方法。 You could consider that BLL.Employee would resolve to a compiled type of BLL_Employee , and that DAL.Employee would resolve to a compiled type of DAL_Employee . 可以认为BLL.Employee将解析为编译型的BLL_Employee ,而且DAL.Employee将解析为编译型的DAL_Employee (This isn't really what happens, but it suits my purposes for illustration.) (这不是真正发生的事情,但是适合我的说明目的。)

When the runtime goes to compare types, it's plainly evident that BLL_Employee != DAL_Employee . 当运行时比较类型时,很明显BLL_Employee != DAL_Employee As a result, declaring DAL.Employee to be a partial class is pointless because there's no other DAL_Employee to pick up the slack and provide the remainder of the implementation. 结果,将DAL.Employee声明为局部类是没有意义的,因为没有其他DAL_Employee可以选择松弛部分并提供其余的实现。

What you want to do is create two files in the same namespace. 您要做的是在同一个命名空间中创建两个文件。

// Employee.cs (In a BLL folder)
namespace BLL
{
    public class Employee
    {
        // Custom business logic.
    }
}

// Employee.cs (In the DAL folder)
namespace DAL
{
    public class Employee
    {
        // Custom data access code here. 
        // Not overwritten by code generator
    }
}

// Employee.designer.cs (In the DAL folder)
namespace DAL
{
    public partial class Employee
    {
        // Generated code goes here.
        // Frequently updated by code generation tools.
        // Do not manually update this code.
    }
}

Further, you don't want to mix business logic with data acess logic, which sounds like the objective of merging the classes in the BLL and DAL namespaces. 此外,您不想将业务逻辑与数据访问逻辑混合在一起,这听起来像是将BLL和DAL名称空间中的类合并的目标。 Major no-no. 大不行 Keep them separate. 将它们分开。 You may consider introducing a 3rd set of classes that you invoke which hide away the data access classes in your DAL namespace and simply return suitable business objects from your BLL namespace. 您可以考虑引入您调用的第三组类,它们隐藏了DAL名称空间中的数据访问类,并仅从BLL名称空间中返回了合适的业务对象。 That way, your DAL namespace doesn't have to know about your BLL namespace, and the BLL namespace doesn't have to know about the DAL namespace. 这样,您的DAL命名空间就不必知道BLL命名空间,而BLL命名空间也不必知道DAL命名空间。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM