Inheriting from entity classes and extending the class

1.8k views Asked by At

I used Entity Framework 4.0 for creating my Data Access Layer. Then I found that my Business Logic Layer has the same objects as DAL but with some extensions (i.e, more properties, some functions, and data validation at setters...).

I planned to have DAL and BLL in separate projects and was looking for best practice to use entity classes in BLL and prevent redundancy in code.

As I searched and there are two major ideas:

  1. extending entity classes inside the same project by partial classes
  2. Using interfaces (implemented by entity class and relevant BLL class). Former is more popular among programmers.

Disadvantages for above solutions:

  1. We need to add the code at the same project as part of the partial class. This is good for adding properties and methods but it's not good for overriding something (i.e, adding validations before setting a property at Business Logic Layer)
  2. If the entity model is changed, we need to manually extract the interfaces from entity classes again and also another change in BLL related class is needed (two manual work around).

My question is why we simply doesn't inherit our BLL classes from relevant entity classes and extend/override their methods and properties ?

1

There are 1 answers

2
Adam Robinson On BEST ANSWER

One thing that you need to keep in mind is that ORM's like the Entity Framework don't actually create a simple data access layer (when viewed through the general 3-tier architecture). What they give you is much more of a business layer with a slightly more granular level of control over the data access interaction. I think it can be argued that EF essentially becomes your DAL and the context and entity types can be the BLL.

The line's a lot easier to see when viewed through more of an MVC or MVVM architecture, where you have a model (your EF layer), a controller or viewmodel (where the business logic sits, which encapsulates the model), and a view.

Anyhow, because EF actually has to instantiate the entity types directly, inheriting wouldn't do you much good because EF won't use your subtype as the returned entity. The solution for validation and similar tasks in EF is to make use of both partial classes (which you obviously know about) and partial methods. The default code-generation templates in EF produce partial methods for all scalar properties for OnPROPERTYNAMEChanging and OnPROPERTYNAMEChanged.

For instance, if you have an int UserId property on your User entity type, you can create a partial class that looks like this:

public partial class User
{
    partial void OnUserIdChanging(int newUserId)
    {
        // do something
    }

    partial void OnUserIdChanged()
    {
        // do something
    }
}

You can, of course, only use one or the other if you like. The advantage that partial methods would have over an inherited call (assuming it was even possible) is that partial methods are non-virtual (so there's no virtual table lookup to call the correct member) and are only compiled as part of the class if there's an actual implementation.

In other words, even though you can go into the designer code and see the declarations for

partial void OnUserIdChanging(int value);
partial void OnUserIdChanged();

If you don't actually add a method body to the function, then the C# compiler completely removes the function and all calls to it from the code, as if it had never been there in the first place. This makes the types smaller and the calls to other properties faster, since it won't have to bother with calling an empty function.