Design pattern for Data Access Layer

前端 未结 5 588
旧时难觅i
旧时难觅i 2020-12-23 15:36

You might feel this is homework, for that I am sorry. I have searched but couldn\'t find a proper answer.

So my question is:

I have several classes and each

5条回答
  •  独厮守ぢ
    2020-12-23 15:59

    Normally, if I can't use any existing framework, I use both the Repository and Active patterns.

    For simplicity, you could use only the Repository pattern. I normally define it like this:

    public interface IEntity { }
    
    //  Define a generic repository interface
    public interface IRepository
        where TEntity : IEntity
    {
        void Add(TEntity entity);
        void AddRange(IEnumerable entities);
        IEntity Get(TKey key);
        IEnumerable GetRange(IEnumerable keys);
        IEnumerable GetAll();
        //  ..., Update, Delete methods
    }
    
    //  Create an abstract class that will encapsulate the generic code
    public abstract class Repository : IRepository
        where TEntity : IEntity
    {
        protected Repository(/*parameter you may need to implement the generic methods, like a ConnectionFactory,  table name, entity type for casts, etc */) { }
    
        public override void Insert(IEntity entity)
        {
            //  do the insert, treat exceptions accordingly and encapsulate them in your own and more concise Exceptions, etc
        }
        //  ...
    }
    
    //  Create the entities classes, one for each table, that will represent a row of that table
    public class Car : IEntity {/* Properties */}
    
    //  Create a specific repository for each table
    //  If the table have a composed key, just create a class representing it
    public class CarRepository : Repository
    {
        public CarRepository() {/* pass the base parameters */}
    
        // offer here your specific operations to this table entity
        public IEnumerable GetByOwner(PersonKey ownerKey)
        {
            //  do stuff
        }
    }
    

    Obviously, when doing your own implementations, you must take into account thread safety making good using of transactions, specially across diferent entity repositories.

    //  simple example
    ITransaction t = TransactionFactory.GetNewTransaction();
    t.begin();
    try{
        //  create person entity
        personRepository.Add(person, t);
        //  create cars assigned to person
        carRepository.AddRange(cars, t);
        t.commit();
    }catch(Exception){
        t.rollback();
    }
    

    Just be sure that you really want to create your own DAL since it can end beeing extremelly complex, specially trying to develop the most generic solution.

提交回复
热议问题