Let Me Handle the Data Store..........

In a previous post we mentioned the Multi-Tier Architecture and how it allows us to separate the Presentation Layer from the Business Layer and the Data Access Layer. We talked about all the advantages of the 'separation of concerns' concept and how it allows each and every layer to do its job independently from the other layers. In this post we're going to look into more detail at the Data Access Layer and how we're applying the 'separation of concerns' concept here.

Sometimes when designing a new website, one might be unsure as to which data storage medium to use, how to call this medium and where its going to be hosted. The reality is we're spoilt for choice when it comes to Database Management Systems (DBMS), whether it is MS SQL SERVER, My SQL, Oracle or Cloud Data Storage services. We should always keep our options open when choosing a specific DBMS, what suits our requirements now might not be suitable in a year's time. We were trying to find a solution where code related to data access would be unchanged (or at least the changes involved would be minimal) if we were to change the underlying data storage medium. That is where we the Repository design pattern come in.

 Using the Repository Pattern, the business logic layer always interacts with the Data Access Layer using the same functions or 'API' irrelevant of the underlying Data Storage medium. The Repository pattern neatly abstracts the internal mechanics of how calls to the repository are translated into the actual data access calls to the data store as shown in the diagram below:

 The business logic layer can manipulate objects from the repository as if they were a collection or a list in the desired fashion and it is the repository's responsibility  to encapsulate and persist those objects using the API or code syntax of the underlying Data Store.

Here are a few advantages of using the Repository pattern in our Data Access Layer in place of direct access to the Data Storage medium:

  • Less Duplication of Code
  • Automation of Unit testing can be facilitated for the DAL
  • High level Data security policies can be enforced within this layer
  • Centralized Caching
  • Providing Strongly typed object to the Business Logic Layer

The following code demonstrates a simple Generic Repository Interface which is exposed to higher levels in our Multi-Tier architecture:

 public interface IRepository<E>
    {
        string KeyProperty { get; set; }

        void Add(E entity);
        void AddOrAttach(E entity);
        void DeleteRelatedEntries(E entity);
        void DeleteRelatedEntries
        (E entity, ObservableCollection<string> keyListOfIgnoreEntites);
        void Delete(E entity);

        ObjectQuery<E> DoQuery();
        ObjectQuery<E> DoQuery(ISpecification<E> where);
        ObjectQuery<E> DoQuery(int maximumRows, int startRowIndex);
        ObjectQuery<E> DoQuery(Expression<Func<E, object>> sortExpression);
        ObjectQuery<E> DoQuery(Expression<Func<E, object>> sortExpression,
                    int maximumRows, int startRowIndex);

        IList<E> SelectAll(string entitySetName);
        IList<E> SelectAll();
        IList<E> SelectAll(string entitySetName, ISpecification<E> where);
        IList<E> SelectAll(ISpecification<E> where);
        IList<E> SelectAll(int maximumRows, int startRowIndex);
        IList<E> SelectAll(Expression<Func<E, object>> sortExpression);
        IList<E> SelectAll(Expression<Func<E, object>> sortExpression,
                    int maximumRows, int startRowIndex);

        E SelectByKey(string Key);

        bool TrySameValueExist(string fieldName, object fieldValue, string key);
        bool TryEntity(ISpecification<E> selectSpec);

        int GetCount();
        int GetCount(ISpecification<E> selectSpec);
    }

 

A system can even have different implementations  of this Interface accessing different storage mediums. Using the Inversion of Control concept as explained in previous posts one could have a system which utilizes different implementations  at run time. This could prove to be very useful especially when your system is being used on different platforms such as a 'website' and as a 'native mobile application'. The Repository could be using two completely different and separate Data Storage media but the Business Logic layer would still be making the same calls and manipulating the same domain models.

Thank you for reading,

Shaun