Robert
Robert

Reputation: 2523

Inheritance and generic classes

I recently did some work on adjusting the Dapper to my needs and it works quite good but I noticed I have certain code that repeates and I want to minify that as much as possible. Current way this works is:

I have a base DAL class that does some basic operation such as Save, Delete, Get, etc. Along with that it has a property named IsNew that...well...you've guessed determines if it's new or existing entity.

public class DalBase
{
   public bool IsNew
   {
      get;
      private set;
   }

   public static T New<T>()
   {
      // removed for clarity
   }

   public void Get<T>(params object[] parameters)
   {
      // removed for clarity
   }    

   public void Save()
   {
      // removed for clarity
   }

   public void Delete()
   {
      // removed for clarity
   }
}

If I want to define my entity, lets say person, I would do it this way:

public partial class Person
{
    private PersonDal m_dal;

    public bool IsNew
    {
        get
        {
            return m_dal.IsNew;
        }
    }

    public int? PersonID
    {
        get
        {
            return m_dal.PersonID;
        }
    }

    public string PersonName
    {
        get
        {
            return m_dal.PersonName;
        }
        set
        {
            m_dal.PersonName = value;
        }
    }

    public string PersonSurname
    {
        get
        {
            return m_dal.PersonSurname;
        }
        set
        {
            m_dal.PersonSurname = value;
        }
    }

    public DateTime? PersonDateOfBirth
    {
        get
        {
            return m_dal.PersonDateOfBirth;
        }
        set
        {
            m_dal.PersonDateOfBirth = value;
        }
    }

    private Person()
    {
        m_dal = DalBase.New<PersonDal>();
    }

    public static Person New()
    {
        return new Person();
    }

    public static Person Get(int PersonID)
    {
        var personDal = DalBase.Get<PersonDal>(PersonID);

        if (personDal == null)
            return null;

        var person = new Person();
        person.m_dal = personDal;
        return person;
    }

    private class PersonDal : DalBase
    {
        public int? PersonID
        {
            get;
            set;
        }

        public string PersonName
        {
            get;
            set;
        }

        public string PersonSurname
        {
            get;
            set;
        }

        public DateTime? PersonDateOfBirth
        {
            get;
            set;
        }

        private PersonDal()
        {
            IsNew = true;
        }
    }
}

As you can see my DAL is contained inside the Entity class. This way I can do all sorts of things like mappings, preliminary checks before update or insert, etc. But, this is not why I copy pasted this code here :)

What I want to do is somehow eliminate IsNew from the entity because it will repeate on every entity definition and it seems a bit redundant AND more because I might be thinking of adding some columns that are common for all tables such as DateOfEdit, UserEdit, etc... As you can see it would be very handy to add it in one place and than inherit it and just keep specific columns in each entity definition.

What I tried doing by now is using generics like this:

public class EntityBase<T> where T : DalBase
{
    protected T m_dal;

    public bool IsNew
    {
        get
        {
            return m_dal.IsNew;
        }
    }
}

This would allow me to inherit base entity with specific Dal class so I can have my person entity defined as such:

public partial class Person : EntityBase<PersonDal>

The problem with this approach is that the PersonDal is private class of Person entity and as such has less accessibility than the entity itself and if I just define it as public - well it beats the whole purpose since the DAL is used only by the entity that is concerned with it!

Is there any other way that we could achieve this?

Upvotes: 0

Views: 113

Answers (1)

Dexion
Dexion

Reputation: 1101

DAL has nothing to do with the entities. You mix the concepts here. Use DAL as an individual class, not as a member field/variable of your entity classes and pass the entity types to DAL. If you have to have the DAL in your entities, use DI and pass the DAL instance in the constructor.

Or if you want to use your original approach, create a simple EF project with two entity types and check how it works.

Upvotes: 1

Related Questions