views:

117

answers:

7

Is it OK to implement BLL and DAL using partial class this way:

 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.

+1  A: 

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. 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). In this case, the constructors take things like Id or Name -- something you use to identify the object. It passes this down to the DAL and builds the object based on the result set.

Brad
+3  A: 

It's unclear what you're trying to achieve by making your classes 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.

Perhaps if you can explain the problem you are trying to solve, you may be able to get a better answer to your question.

LBushkin
I want to have BLL and DAL separated in namespaces but in one class, is it possible?
CSharpNoob
@CSharpNoob: No, that's not possible. A class can only be part of a single namespace - splitting implementation across namespaces with partial classes doesn't work. What you can do, is implement two separate classes, and have one inhert from the other - but I'm not sure that's going to get you where you want to be. So far you still haven't explained what *problem* you're trying to solve. Namespaces and inheritance are just tools ... you have to apply them in the right ways for the right reasons.
LBushkin
+1  A: 

You can't use partial classes that way - BLL.Employee is a different class than DAL.Employee because they are in different namespaces. You'll just have 2 partial classes with no other parts.

Even if they did represent the same class, they can't both define a method with the same signature.

arootbeer
A: 

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. 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. 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. This will make the code more re-usable and testable.

Bernd
A: 

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.bl.cs

Then your Employee.cs code would look like this:

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

And Employee.bl.cs would look like this:

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.

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. 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. All of the database access is done through one interface. You could also create an interface and have multiple implementations of the repository; that way, you could have a way to store Employee instances in a file, for example, without having to change the Employee class.

Jacob
what do you mean by having repository? can you please demonstrate that in your suggestion.. thanks
CSharpNoob
A: 

(1) Put your business objects/table entities in a shared particular place. 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. So put them in a shared place with well-named folders.

(2) Don't put business logics/data logics in entities. You see you put GetListOfEmployees in 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.

(3) See GetListOfEmployees method in both BLL and DAL, they are totally the same! But the method in BLL is supposed to contain "Business Logics", that is why we call it BL-Layer. In BLL methods' names are considered to be "business words", e.g. in the method it tells the DAL "I need all the employees, order by name". BLL tells "what I need" and DAL do the picking. Methods in DAL have no business things.

Danny Chen
A: 

One thing that might be escaping the OP is that namespaces are just a fanciful way of performing name-mangling of a sort. 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. (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. 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.

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

Mike Hofer