Scott Harrison - The golden apples
Henry Parker's Robot Wars

ASP.Net, ADO, MS Access
C# Unit of Work - Repository Pattern - Object Oriented Designs

C# Unit of Work - Repository Pattern - Object Oriented Designs

(31 hits)

Overview: I have built five unit tests to demonstrate the Unit of Work, Repository pattern. The UnitOfWork has only one method, CommitChanges. The UnitOfWork contains one or more repository types, such as, the addressBookRepository. Each repository type is derivated from a repository parent class. The repository parent class is a generic class of type T where T is a class. In this case, the generic type is AddressBook.

Hits=10 The repository pattern allows you to create custom linq methods like the one created call GetAddressBook. Try and use the Foreign Key associated include tables where possible. When using the eager or lazy loading tables are not possible then use linq.

        [TestMethod]
        public void TestGetAddressBooks()
        {
            UnitOfWork unitOfWork = new UnitOfWork();
            Task<List<AddressBook>> resultTask = Task.Run<List<AddressBook>>(async () => await unitOfWork.addressBookRepository.GetAddressBooks("customer"));

            IList<string> list = new List<string>();
            foreach (var item in resultTask.Result)
            {
                Console.WriteLine($"{item.Name}");
                list.Add(item.Name.ToUpper());
            }
            Assert.IsTrue(list.Contains("BOB SMITH") && list.Contains("PAM NISHIMOTO"));
        }
[TestMethod]
        public void TestGetAddress()
        {
            UnitOfWork unitOfWork = new UnitOfWork();
            Task<AddressBook> resultTask = Task.Run<AddressBook>(async () => await unitOfWork.addressBookRepository.GetObjectAsync(1));

            Console.WriteLine($"{resultTask.Result.FirstName}");

            Assert.AreEqual(resultTask.Result.FirstName, "David");
        }
        [TestMethod]
        public void TestUpdateAddressBook()
        {
            UnitOfWork unitOfWork = new UnitOfWork();
            Task<AddressBook> resultTask = Task.Run<AddressBook>(async () => await unitOfWork.addressBookRepository.GetObjectAsync(1));

            AddressBook addressBook = resultTask.Result;
            addressBook.FirstName = "David2";
            unitOfWork.addressBookRepository.UpdateObject(addressBook);
            unitOfWork.CommitChanges();

            var query = unitOfWork.addressBookRepository.GetObjectAsync(1);

            string name = query.Result.FirstName;

            Assert.AreEqual(name, "David2");


        }
        [TestMethod]
        public void TestAddandDeleteAddressBook()
        {
            UnitOfWork unitOfWork = new UnitOfWork();
            AddressBook addressBook = new AddressBook();
            addressBook.FirstName = "James";
            addressBook.LastName = "Dean";
            addressBook.Name = "James Dean";
            unitOfWork.addressBookRepository.AddObject(addressBook);
            unitOfWork.CommitChanges();

            IQueryable<AddressBook> query = unitOfWork.addressBookRepository.GetObjectsAsync(a => a.Name == "James Dean");

            foreach (var item in query)
            {
                Assert.AreEqual(item.Name, "James Dean");

                unitOfWork.addressBookRepository.DeleteObject(item);
            }
            unitOfWork.CommitChanges();

        }
        [TestMethod]
        public void TestDeleteAddressBooks()
        {
            List<AddressBook> list = new List<AddressBook>();
            UnitOfWork unitOfWork = new UnitOfWork();
           
            for (int i = 1; i < 10; i++)
            {
                AddressBook addressBook = new AddressBook();
                addressBook.Name = "Test" + i.ToString();
                list.Add(addressBook);
           
            }
            unitOfWork.addressBookRepository.AddObjects(list);
            unitOfWork.CommitChanges();

            IQueryable<AddressBook> query = unitOfWork.addressBookRepository.GetObjectsAsync(a => a.Name.Contains("Test"));

            list.Clear();

            foreach (var item in query)
            {
                list.Add(item);
            }

            unitOfWork.addressBookRepository.DeleteObjects(list);
            unitOfWork.CommitChanges();

        }

Overview: Hits=10 The DbContext is the Entity Framework table definitions and DBSet Collections. It also has the virtual ICollections for eager or lazy loading of the associated dependency tables defined by the foreign Key constraint. The CommitChanges method of the Unit of Work Saves the changes to the database context to the database.

 public class UnitOfWork
    {
        public AddressBookRepository addressBookRepository = null;
        DbContext db = new Entities();
        public UnitOfWork()
        {
            addressBookRepository=new AddressBookRepository(db);
    
        }
        public void CommitChanges()
        {
            db.SaveChanges();
        }
    }

Overview: Hits=9 The Repository Generic class receives the DbContext from the UnitOfWork Container class. The Repository Generic class provides the Create, Update, Delete, and Find methods for a Generic Class, in this case, AddressBook. The Repository Generic class can add a range of objects in a List or remove a range of objects in the list from the database of Type T.

   public class Repository<T> where T : class
    {
        private DbContext _dbContext;

        public Repository(DbContext dbContext)
        {
             _dbContext=dbContext;  
        }
        public void UpdateObject(T dataObject)
        {

            _dbContext.Entry(dataObject).State = System.Data.Entity.EntityState.Modified;
         }
        public async Task<T> GetObjectAsync(int id)
        {
                Task<T> result = _dbContext.Set<T>().FindAsync(id);
                return await result;
        }
        public IQueryable<T> GetObjectsAsync(Expression<Func<T, bool>> predicate)
        {
            IQueryable<T> result = _dbContext.Set<T>().Where(predicate);
            return result;
        }
        public void DeleteObject(T dataObject)
        {

                _dbContext.Set<T>().Remove(dataObject);

        }
        public void DeleteObjects(List<T> dataObjects)
        {

                _dbContext.Set<T>().RemoveRange(dataObjects);
         }

        public void AddObject(T dataObject)
        {

                _dbContext.Set<T>().Add(dataObject);

        }
        public void AddObjects(List<T> dataObjects)
        {
            _dbContext.Set<T>().AddRange(dataObjects);
        }
    }

Overview: I cast the dbContext as an Entities class. The entities class contains the public virtual DbSet<AddressBook> AddressBooks { get; set; } setter and getter required by the linq expression.

    public class AddressBookRepository: Repository<AddressBook>
    {
        Entities _dbContext;
        public AddressBookRepository(DbContext db):base(db)
        {
            _dbContext = (Entities) db;
        }
        
        public async Task<List<AddressBook>> GetAddressBooks(string keyCode)
        {


                Task<List<AddressBook>> resultList = (from a in _dbContext.AddressBooks
                                                                      join b in _dbContext.UDCs on a.PeopleXrefId equals b.XRefId
                                                                      where b.KeyCode == keyCode
                                                                      orderby a.Name
                                                                      select a

                    ).ToListAsync<AddressBook>();

                    return await resultList;


        }
    }

Hits=11 In short, I have demonstrate the Unit of Work repository pattern. The unit of Work should be aligned with the UML use cases that control the flow of business logic. The Unit of Work is a powerful way to accomplish complex tasks that can be compared to the business logic diagrams.

....

...<<<Register to correspond>>> ...

Members : 152
Name:
Email:

Register to View

Help