Saturday, October 10, 2015

An Implementation of Unity of Work and Repository Pattern

 

Objective:

1. Keep a clean separation of concerns.

2. Implement business logic from acceptance test/ use case ( ATDD/ BDD )

3. A complete implantation on Repository and Unit of Work with IoC and Unit Testing (BDD).

.

Unity of Work Pattern:

One of the most common design patterns in enterprise software development is the Unity of Work. According to Martin Fowler, the Unity of Work pattern “Maintains  a list of objects affected by a business transaction and coordinates the writing out of changes and resolution of concurrency problems".

In a way, you can think of the Unit of Work as a place to dump all transaction-handling code. The responsibilities of the Unit of Work are to:

  • Manage transactions.
  • Order the database inserts, deletes, and updates.
  • Prevent duplicate updates. Inside a single usage of a Unit of Work object, different parts of the code may mark the same Invoice object as changed, but the Unit of Work class will only issue a single UPDATE command to the database.

The unity of work pattern isn't necessarily something that you will explicitly build yourself, almost every persistence tool already aware of it. The Entity Framework also have implementation of Unity of Work. SaveChanges() give us feature of unity work. Which allow us to save changes of list of objects together into database. But As I want decouple my business logic from database so the implementation of Unity of Work is

 

1 public interface IUnityofWork : IDisposable
2
3 {
4
5 void Commit();
6
7 }
8
9

The Commit() function work same as SaveChanges() in EntityFramework. If we use update records through context directly then we do not need really to maintain transaction but as we also have some existing stored procedure need to call and also for  bulk copy operation, we also need to maintain transaction explicitly. 

The implementation of Unity Of Work for Entity Framework as

 


1 1 public class UnityOfWorkBase
2 2 {
3 3 private bool _disposed = false;
4 4 protected DbContext Context;
5 5 public void Commit()
6 6 {
7 7 Context.SaveChanges();
8 8 }
9 9 public void Dispose()
10 10 {
11 11 Dispose(true);
12 12 GC.SuppressFinalize(this);
13 13 }
14 14 protected virtual void Dispose(bool disposing)
15 15 {
16 16 if (_disposed)
17 17 return;
18 18 if (disposing)
19 19 {
20 20 if (Context != null)
21 21 {
22 22 Context.Dispose();
23 23 Context = null;
24 24 }
25 25 }
26 26 _disposed = true;
27 27 }
28 28
29 46 }

 


Repository Pattern


Unity of Work provided me decoupling from database operation which we do not need to implement for Unit Testing scenario.

Next for decoupling database entity I have created repository for each entity which provide common functions as in memory object like List.

According to Martin Fowler, “Mediates between the domain and data mapping layers using a collection-like interface for accessing domain objects”.

Repository act-like in memory collection like List for .NET which provide common function like Add(), Remove(),  and enumeration functionality.  LINQ also provide extensive functionality on List and also Entity framework. 

The generic implementation of Repository pattern as follows:

 


1 1 public interface IRepository<T> where T : class
2 2 {
3 3 IQueryable<T> Query();
4 4
5 5 IEnumerable<T> FindAll();
6 6
7 7 IQueryable<T> Find(Expression<Func<T, bool>> predicate);
8 8
11 11 T First(Expression<Func<T, bool>> predicate);
12 12
13 13 void Add(T entity);
14 14 void Add(List<T> entity);
15 15
16 16 void Delete(T entity);
17 17
18 18 void Attach(T entity);
19 19
20 20 bool BatchInsert(IList<T> entity, string tableName);
21 21
22 22 }

BulkCopy is faster than normal insertion of multiple records as a batch. So in the repository I also have provided implementation. This implementation is suitable for both List and also DbSet.

The implementation of Repository for unit testing as follows:

 


1 1 public class TestRepository<T>:IRepository<T> where T:class
2 2 {
3 3 private IList<T> _repostiory = new List<T> ();
4 4 public IQueryable<T> Query()
5 5 {
6 6 return _repostiory.AsQueryable();
7 7 }
8 8
9 9 public IEnumerable<T> FindAll()
10 10 {
11 11 return _repostiory;
12 12 }
13 13
14 14 public IQueryable<T> Find(Expression<Func<T, bool>> predicate)
15 15 {
16 16 return _repostiory.AsQueryable().Where(predicate);
17 17 }
18 18
19 19
24 24 public T First(Expression<Func<T, bool>> predicate)
25 25 {
26 26 return _repostiory.AsQueryable().FirstOrDefault(predicate);
27 27 }
28 28
29 29 public void Add(T entity)
30 30 {
31 31 _repostiory.Add(entity);
32 32 }
33 33
34 34 public void Add(List<T> entities)
35 35 {
36 36 foreach (var entity in entities)
37 37 {
38 38 _repostiory.Add(entity);
39 39 }
40 40 }
41 41
42 42 public void Delete(T entity)
43 43 {
44 44 _repostiory.Remove(entity);
45 45 }
46 46
47 47 public void Attach(T entity)
48 48 {
49 49 throw new NotImplementedException();
50 50 }
51 51
52 52 public bool BatchInsert(IList<T> entities, string tableName)
53 53 {
54 54 Add(entities.ToList());
55 55 return true;
56 56 }
57 57 }

In the TestRepository example the repository is a in memory List object.

This repository is suitable for tables and views. But As we already have existing implication and some logics are in database. So I need to provide an interface to call stored procedure as well.

Repository for stored procedure will provide common function to execute stored procedure and retrieve value.

The interface of repository for stored procedure as

 


1 1 public interface IRepository_SP<T>
2 2 {
3 3 IEnumerable<T> ExecSqlQuery( params object[] parameters);
4 4 Int32 ExecSqlCommand(params object[] parameters);
5 5 }

The implementation of IRepostory_SP for unit testing is also simple as for query records it should return List and for executing command it return 0.

 


1 1 public class TestRepositorySp<T> : IRepository_SP<T> where T:class
2 2 {
3 3 public List<T> Items { get; set; }
4 4
5 5 public TestRepositorySp(List<T> items)
6 6 {
7 7 Items = items;
8 8 }
9 9
10 10 public IEnumerable<T> ExecSqlQuery(params object[] parameters)
11 11 {
12 12 return Items;
13 13 }
14 14
15 15
16 16 public int ExecSqlCommand(params object[] parameters)
17 17 {
18 18 return 0;
19 19 }
20 20 }

 


The example for mocking the stored procedure


1 var mocksecuritySp = new Mock<IRepository_SP<int>>();
2 mocksecuritySp.Setup(e => e.ExecSqlCommand(It.IsAny<ObjectParameter>()))
3 .Returns(0);
4 _testUnityOfWork.DeleteCommandRepositorySp = mocksecuritySp.Object;

This article is based on article https://msdn.microsoft.com/en-us/library/ff714955.aspx.

I wrote article on Specflow and FluentAssertion long time ago. Here is the link

http://ciintelligence.blogspot.ca/2014/05/atdd-acceptance-test-driven-development.html

Sunday, October 4, 2015

Code Smells: Long Method Refactoring using Resharper

The object programs that live best and longest are those with shorts methods.  Programmers new to objects often feel that no computation ever takes place, that object programs are endless sequences of delegation.

     Since the early days of programming people have realized that the longer a procedure is, the more difficult  it is to understand. Modern OO languages have pretty much eliminated overhead of in-process calls.There is still overhead to the reader of the code because you have to switch context to see what sub procedure does. But the real key to making it easy to understand small method id good naming. If you have a good name for a method you don't need to look at the body.

Refactoring:

     A heuristic we follow is that whenever we feel that need to comment something, we write a method instead. Such a method contains the code that was commented but is named after the intention of the code rather than how it does it. This is also the way to refactor "Comments" code smell.

Ninety-nine percentage of the time, all you have to do to shorten a method is Extract Method . Find parts of the method that seem to go nicely together and make a new method.

If you have a method with lots of parameters and temporary variable  the you can follow the approach I mentioned in another article

Refactoring Long Parameter List:

I have already written an article on refactoring long parameter list : http://ciintelligence.blogspot.com/2015/09/code-smells-long-parameter-list.html . If you've tried that, and you still have too many temps and parameters, its time to get out the heavy artillery Replace Method with Method Object.

 

Extract Method :

Extract method is one of the most common refactoring I do.  I look at a method that is too long or look at code that needs a comment to understand its purpose. I then  turn that fragment of code into its own method.

     Mechanics:

  • Create a new method, and name it after the intention of the method ( name it by what it does, not by how it does it)
  • Copy the extracted code from the source method into the new target method.
  • Scan the extracted code for references to any variables that are local in scope to the source  method. These are local variables and parameters to the method.
  • See whether any temporary variables are used only within this extracted code. If s, declare them in the target method as temporary variables.
  • Look to see whether any of these local-scope variables are modified by the extracted code. If one variable is modified, see whether you can treat the extracted code as a query and assign the result to the variable concerned. if this is awkward, or if there is more than one such variable, you can't extract the method as it stands. You may need to use Split Temporary Variable  and try again. You can eliminate temporary variables with Replace Temp with Query.
  • Pass into the target method as parameters local-scope variables that are read from the extracted code.
  • Compile when you have dealt with all the call-scoped variables
  • Replace the extracted code in the source method with a  call to the target method.
  • Compile and test.

Example using Resharper:

      Here is the initial code with we are going to refactor. Things to notice here  PrintOwing function, has some comments to understand what is the purpose of following portion of code. This is Comments Code Smell. These are the places we can apply Extract Method.

Initial code:

nopm1[1]


  • Example for extracting method without any arguments:

     Using ReSharper Extract Method we can easily move the code in method so that we do not require to comment the code but the important thing is to give proper name of the extracted method so that we do not need to go inside the method to understand the reason of the code. The shortcut for Extract Method in Resharper is Ctrl+Alt + M or (Ctrl R, M)

nopm2a[1]


It will ask to give name of the method. As the method is printing banner so the name of the method could be as

nopm3a[1]


  • Extracting Method for Local Variable

         ReSharper is intelligent enough to understand the local variable used inside code. So it will automatically take local variable as parameter to the extracted method. Here as example, outstanding variable is used for print detail . We can use same Extract Method refactoring from Resharper without any modification.

nopm4[1]

The outstanding variable is passed as argument inside PrintDetails method automatically.


  • Extract Method and Reassigning a local variable

This refactoring needs to organize the code little so that it can declare local variable inside method and pass the result as return value. outstanding value is generated inside calculate outstanding portion of code. First task will be to take outstanding variable close to calculation.

nopm5[1]


As the outstanding variable is moved just before calculation. So doing extract method on calculation section Resharper will automatically return the result of the calculation and reassign to a local variable.

nopm7[1]


  • Final Code after Refactoring

    The code which need to be commented, are moved to methods using Extract Method. This replace long method code into small methods sequence. As because the extracted method names are self explanatory so we do not need to go inside each code to understand what is the purpose of the method.

nopm8[1]

Output this refactoring changed PrintOwing method into three line of code which do same operation and code need less effort to understand what this PrintOwing is doing.