【问题标题】:3-Layer Architecture Pattern三层架构模式
【发布时间】:2010-09-16 14:23:44
【问题描述】:

这样使用partial class实现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;
   }
 }
}

或任何其他建议?提前致谢。

【问题讨论】:

  • 您的 DAL 和 BLL 类不会合并,因为它们位于不同的命名空间中。
  • 为什么不使用现有的 DAL 而不是自己发明?在此线程中查看我的答案:stackoverflow.com/questions/3704802/…

标签: c# architecture layered


【解决方案1】:

目前还不清楚您通过创建课程partial 想要达到什么目的。当您需要将单个类拆分为多个文件时,部分类很有用 - 通常是因为一个或多个部分是机器生成的。在这种情况下,将机器生成的部分与人工编辑的部分分开有助于避免一组更改覆盖或破坏另一组。

在您的示例中,使用 partial 并没有多大效果,因为两个 Employee 类位于不同的命名空间中 - 它们不会合并到一个实现中。

也许如果你能解释你试图解决的问题,你可能会得到更好的答案。

【讨论】:

  • 我想将 BLL 和 DAL 在命名空间中分开,但在一个类中,这可能吗?
  • @CSharpNoob:不,这是不可能的。一个类只能是单个命名空间的一部分——使用部分类在命名空间之间拆分实现是行不通的。你可以做的是实现两个独立的类,并且从另一个继承一个 - 但我不确定这会让你到达你想去的地方。到目前为止,您还没有解释您要解决的问题。命名空间和继承只是工具……您必须出于正确的原因以正确的方式应用它们。
【解决方案2】:

很多都归结为偏好,但就个人而言,我会为 Employee/EmployeeCollection 创建创建一个Factory 类,而不是将它放在对象本身中。如果我确实将其放入对象中,我会将对象创建方法设为静态,这样您就不必为了创建真实对象而实例化一个虚拟对象。

过去,我将创建逻辑(包括 DAL 调用)构建到实际的构造函数中(使用依赖注入将数据配置获取到对象中)。在这种情况下,构造函数采用IdName 之类的东西——你用来识别对象的东西。它将这个传递给 DAL 并根据结果集构建对象。

【讨论】:

    【解决方案3】:

    您不能以这种方式使用部分类 - BLL.Employee 与 DAL.Employee 是不同的类,因为它们位于不同的命名空间中。您将只有 2 个没有其他部分的部分类。

    即使它们确实代表同一个类,它们也不能同时定义具有相同签名的方法。

    【讨论】:

      【解决方案4】:

      如果我错了,请纠正我,但通过在两个不同的命名空间(DAL 和 BLL)中创建部分 Employee 类,您只需创建两个不同的类。看起来您想要创建一个包含两个部分类的单个类 - 在您的示例中不是这种情况。在您的代码示例中,您可以简单地删除部分标识符。

      除此之外,在我看来,将业务逻辑与用户界面和数据访问分开是一种好方法。因此,要么使用三个程序集,要么只是在同一个 Visual Studio 项目中使用三个文件夹。这最终始终取决于您的解决方案有多复杂。

      特别是在使用 LINQ to SQL 或实体时,我发现在数据访问层中保留尽可能多的 LINQ 代码是一种很好的做法。这将使代码更具可重用性和可测试性。

      【讨论】:

        【解决方案5】:

        (1) 将您的业务对象/表实体放在一个共享的特定位置。假设您有这些类:Employee(可能引用表Employees 中的一行)、Department(可能引用表Departments 中的一行)等。这些类可能在您的所有层中都使用。因此,请将它们放在具有良好命名文件夹的共享位置。

        (2) 不要将业务逻辑/数据逻辑放在实体中。你看你把GetListOfEmployees放在Employee中。但实际上他们之间几乎没有什么关系。应该有一个叫EmployeeManager的类,里面有对员工的查找、更新、删除等动作。

        (3) 在BLL 和DAL 中参见GetListOfEmployees 方法,它们完全一样!但是BLL中的方法应该包含“业务逻辑”,这就是我们称之为BL-Layer的原因。在 BLL 中,方法的名称被认为是“商业用语”,例如在方法中它告诉 DAL “我需要所有员工,按姓名排序”。 BLL 告诉“我需要什么”,DAL 负责挑选。 DAL 中的方法与业务无关。

        【讨论】:

          【解决方案6】:

          可能会逃避 OP 的一件事是,命名空间只是一种执行 name-mangling 的奇特方式。您可以认为BLL.Employee 将解析为BLL_Employee 的编译类型,而DAL.Employee 将解析为DAL_Employee 的编译类型。 (这并不是真正发生的事情,但它符合我的说明目的。)

          当运行时去比较类型时,很明显BLL_Employee != DAL_Employee.因此,将 DAL.Employee 声明为部分类是没有意义的,因为没有其他 DAL_Employee 可以弥补这一缺陷并提供其余的实现。

          您要做的是在同一个命名空间中创建两个文件。

          // 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.
              }
          }
          

          此外,您不希望将 business 逻辑与 data access 逻辑混合,这听起来像是合并 BLL 和 DAL 命名空间中的类的目标。主要禁止。将它们分开。您可以考虑引入您调用的第三组类,它们隐藏了 DAL 命名空间中的数据访问类,并简单地从 BLL 命名空间返回合适的业务对象。这样,您的 DAL 命名空间不必知道您的 BLL 命名空间,BLL 命名空间也不必知道 DAL 命名空间。

          【讨论】:

            【解决方案7】:

            其他人都是正确的,这会创建两个单独的类。为了不创建两个单独的类并通过部分类将数据与逻辑分开,您可以在项目中包含以下两个文件:

            • Employee.cs
            • Employee.bl.cs

            那么您的 Employee.cs 代码将如下所示:

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

            Employee.bl.cs 看起来像这样:

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

            虽然我认为使用Repository 类来检索数据比在Employee 中使用GetListOfEmployees 更合适。

            更新:

            当我说存储库时,我指的是Repository design pattern。存储库是用于检索和存储对象(例如从关系数据库)的接口。如果您使用的是 LINQ to SQL 或 ADO.NET 实体框架之类的 ORM,它们通常会自动生成填充此角色的类。但是,如果您编写自己的数据库访问代码,则可以像这样创建自己的存储库类:

            public class Repository
            {
                public Repository(string connectionString)
                {
                    // ...
                }
            
                public IEnumerable<Employee> GetEmployees()
                {
                    return GetEmployeesFromDb();
                }
            
                public Employee GetEmployeeById(Guid id)
                {
                    // ...
                }
            
                public void StoreEmployee(Employee employee)
                {
                    // ...
                }
            
                // etc.
            }
            

            这样做的好处是您不必在您的Employee 类或任何其他持久类中放置数据库代码。所有的数据库访问都是通过一个接口完成的。您还可以创建一个interface 并拥有多个存储库实现;这样,您就可以将Employee 实例存储在文件中,例如,无需更改Employee 类。

            【讨论】:

            • 拥有存储库是什么意思?你能在你的建议中证明这一点吗..谢谢
            猜你喜欢
            • 2017-03-24
            • 2011-06-02
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-11-16
            • 2012-02-27
            相关资源
            最近更新 更多