locked
Class inheritance with properties RRS feed

  • Question

  • Hi all fellow programmers,

    I am currently trying to get my head around a problem with inheritance in my C# (ASP.NET web) application.

    The structure I am using so far is like this:

    Class library: DAL
    This is where I'm running all my database transactions - mostly CRUD operations.

    Class library: Model
    This contains my Entity Framework edmx file and a folder called BusinessModels which contains classes with only properties to transfer data from the UI to the DAL.

    Right now I have the following class hierachy:

    Room
    PrivateRoom
    BusinessRoom

    Where PrivateRoom and BusinessRoom are inheriting from Room which contains the general properties/data for a room:

    While this works by doing this in code:

    Room r = new PrivateRoom();

    I can't access the PrivateRoom's properties without casting it to a PrivateRoom object first.

    What I want to achieve is to be able to only transfer a Room object, which is either a PrivateRoom or a BusinessRoom depending on the selection on the UI from the UI to the data access layer.

    Right now I have to ask which type the Room object is before doing CRUD operations on it, in the data access layer, which would lead to a whole lot of work if I were to add a third room type. In other words, I think I'm looking for some sort of a more generic way to pass data from the UI to the data access layer.

    I know some of you might be thinking: "why not make the CRUD operations directly on the UI since you're using EF?" The answer to this is, that I need to have a separate data access layer since more applications needs to access the database with the CRUD operations.

    So, being a novice when it comes to generics, is there any way to do what I want? :-)

    Thanks a lot in advance.


    Wednesday, April 11, 2012 11:59 AM

Answers

  • There is no generic solution, because only the DAL knows the concrete implementation of your relational schemas. The only approach would be using a Dependency Injection  container and inject the necessary handler for the different types. So you can add simply new handler at run-time. I've used Unity in the past, with an XML (app.config) describing the container configuration. So no need to touch the working code.
    • Marked as answer by Lie You Tuesday, April 17, 2012 3:31 AM
    Wednesday, April 11, 2012 12:52 PM
  • There is no getting around the fact that your DAL needs to implement CRUD operations for PrivateRoom and BusinessRoom separately (presuming they have different properties), unless you use an EAV approach - that is, your RDBMS schema is not strongly tied to the properties you define for PrivateRoom and BusinessRoom and instead you create a properties table with entity id/key/value columns.

    Given an object whose declared type is Room and two methods (in the DAL, perhaps) whose parameter types are PrivateRoom and BusinessRoom, there is no way to pass your Room to either of those methods without performing a switch on its type (or casting it to a derived type with the as keyword and checking for null).

    Generics aren't going to help you here because you're not doing anything generic.  In fact, you're doing something quite the opposite - you're getting more specific in your DAL, not more generic.

    • Proposed as answer by servy42 Wednesday, April 11, 2012 4:47 PM
    • Marked as answer by Lie You Tuesday, April 17, 2012 3:31 AM
    Wednesday, April 11, 2012 4:14 PM
  • To add to Evan's reply, another option would be to have each "Room" know how to save itself, but the "Save" operation for each room just calls "Save(this)" out of the DAL.  Then to add a new room the DAL adds a new method for saving that room, and that room calls that method when it is saved.  Then when you just have a general "Room" and need to save it, you call "Save" on it.

    (This is in addition to the other design choices Evan presented, i.e. a Switch on the type.)

    • Edited by servy42 Wednesday, April 11, 2012 4:49 PM
    • Marked as answer by Lie You Tuesday, April 17, 2012 3:31 AM
    Wednesday, April 11, 2012 4:49 PM

All replies

  • There is no generic solution, because only the DAL knows the concrete implementation of your relational schemas. The only approach would be using a Dependency Injection  container and inject the necessary handler for the different types. So you can add simply new handler at run-time. I've used Unity in the past, with an XML (app.config) describing the container configuration. So no need to touch the working code.
    • Marked as answer by Lie You Tuesday, April 17, 2012 3:31 AM
    Wednesday, April 11, 2012 12:52 PM
  • There is no getting around the fact that your DAL needs to implement CRUD operations for PrivateRoom and BusinessRoom separately (presuming they have different properties), unless you use an EAV approach - that is, your RDBMS schema is not strongly tied to the properties you define for PrivateRoom and BusinessRoom and instead you create a properties table with entity id/key/value columns.

    Given an object whose declared type is Room and two methods (in the DAL, perhaps) whose parameter types are PrivateRoom and BusinessRoom, there is no way to pass your Room to either of those methods without performing a switch on its type (or casting it to a derived type with the as keyword and checking for null).

    Generics aren't going to help you here because you're not doing anything generic.  In fact, you're doing something quite the opposite - you're getting more specific in your DAL, not more generic.

    • Proposed as answer by servy42 Wednesday, April 11, 2012 4:47 PM
    • Marked as answer by Lie You Tuesday, April 17, 2012 3:31 AM
    Wednesday, April 11, 2012 4:14 PM
  • To add to Evan's reply, another option would be to have each "Room" know how to save itself, but the "Save" operation for each room just calls "Save(this)" out of the DAL.  Then to add a new room the DAL adds a new method for saving that room, and that room calls that method when it is saved.  Then when you just have a general "Room" and need to save it, you call "Save" on it.

    (This is in addition to the other design choices Evan presented, i.e. a Switch on the type.)

    • Edited by servy42 Wednesday, April 11, 2012 4:49 PM
    • Marked as answer by Lie You Tuesday, April 17, 2012 3:31 AM
    Wednesday, April 11, 2012 4:49 PM