Nanduri's
Knowledge is power but attitude is everything. Join in my long journey of knowledge search, I promise I will share whatever I have seen, whatever I have learned and whatever I have experienced. This is continuous journey so post your questions and lets solve together. Welcome to Nanduri’s Knowledge search.
Monday, July 15, 2013
Start using Single Page Application Template Visual Studio 2012
What do you need First ?
Step 0: Pre-Requisites.
1. Proper VS012 installation will install MVC4 - If not install it from MS Download
2. Download and install ASP.NET and Web Tools 2012.2
Step 1:
Monday, December 17, 2012
Active Directory 123
I've been dinking around in the
System.DirectoryServices
namespace lately trying to update user's in Active Directory. This particular namespace has 2 main component classes: DirectoryEntry
and DirectorySearcher
. After a couple of days (hence no posting) I have successfully accomplished the tasks of querying for and updating users. I will share some basic functionality for looking up and verifying users in Active Directory to lay the foundation for those of you that are interested. It might be useful to read up on LDAP to get a good understanding of what it is and how it works with Active Directory.
Setting up the connection
public static DirectoryEntry GetDirectoryEntry()
{
DirectoryEntry de = new DirectoryEntry();
de.Path = "LDAP://OU=Domain,DC=YourDomain,DC=com";
de.AuthenticationType = AuthenticationTypes.Secure;
return de;
}
Does a User Exist?
Before you update any user information it is probably a good idea to find out if they actually exist in the Active Directory.
Before you update any user information it is probably a good idea to find out if they actually exist in the Active Directory.
public bool UserExists(string username)
{
DirectoryEntry de = GetDirectoryEntry();
DirectorySearcher deSearch = new DirectorySearcher();
deSearch.SearchRoot = de;
deSearch.Filter = "(&(objectClass=user) (cn=" + username + "))";
SearchResultCollection results = deSearch.FindAll();
return results.Count > 0;
}
private String FindName(String userAccount)
{
DirectoryEntry entry = GetDirectoryEntry();
String account = userAccount.Replace(@"Domain\", "");
try {
DirectorySearcher search = new DirectorySearcher(entry);
search.Filter = "(SAMAccountName=" + account + ")";
search.PropertiesToLoad.Add("displayName");
SearchResult result = search.FindOne();
if (result != null)
{
return result.Properties["displayname"][0].ToString();
}
else {
return "Unknown User";
}
}
catch (Exception ex)
{
string debug = ex.Message;
return "";
}
}
The form I created has 2 textboxes (Username & Password) and a submit button. When the button is clicked all the events are fired and if everything checks out the user is updated in Active Directory.
private void btnUpdate_Click(object sender, EventArgs e)
{
if (tbUser.Text != "" && tbPass.Text != "")
{
string username = tbUser.Text.ToString();
string password = tbPass.Text.ToString();
if (UserExists(FindName(username))
{
ModifyUser(FindName(username), username, password);
}
}
}
Modify User Information
public void ModifyUser(string userDisplayName, string username, stringpassword)
{
DirectoryEntry de = GetDirectoryEntry();
de.Username = username;
de.Password = password;
DirectorySearcher ds = new DirectorySearcher(de);
ds.Filter = ("(&(objectclass=user)(objectcategory=person)
(displayname=" + userDisplayName + "))");
ds.SearchScope = SearchScope.Subtree;
SearchResult results = ds.FindOne();
if (results != null)
{
try {
DirectoryEntry updateEntry = results.GetDirectoryEntry();
updateEntry.Properties["department"].Value = "555";
updateEntry.CommitChanges();
updateEntry.Close();
}
catch (Exception ex)
{
tbError.Text = ex.ToString();
}
}
de.Close();
}
Good luck! With a little patience you will find that Active Directory is quite fun to work with. Also keep in mind that this is a very basic example. When you master this you can start pulling data from external data sources, formatting, look them up in Active Directory and then update accordingly!Reading
Sourced from : http://www.willasrari.com/blog/query-active-directory-users-using-c/000133.aspx
Thursday, January 12, 2012
How to setup PHP on windows
Just follow this video and you are good to go
http://www.webassist.com/support/documentation/how-tos/xampp_for_windows.php
Tuesday, January 3, 2012
What is dependency injection
Published: 13 Nov 2009
By: Andrew Siemer
In this article we will address the lack of testability that our current application has. We will do this by making our application conform to the dependency injection pattern. This will allow us to push up all of our dependencies which makes our code considerably more testable than it currently is.
Introduction
In the last article we removed the dependency that our front end and middle tier code had on our data access layer. This provided us with an application that has no ties to the data access technology that is used to connect to the surrounding infrastructure. This made the application more flexible in that the data access code and repositories can be swapped out for something new. The codebase however is no more testable than it has been in all of its previous states.
In this article we will address the lack of testability that our current application has. We will do this by making our application conform to the dependency injection pattern. This will allow us to push up all of our dependencies which makes our code considerably more testable than it currently is.
What is dependency injection?
Dependency Injection as defined by Wikipedia is "the process of supplying an external dependency to a software component. It is a specific form of inversion of control where the concern being inverted is the process of obtaining the needed dependency."
The statement above doesn't clearly describe what this means if your head is not already thinking in this realm. For that reason seeing some code that does not use dependency injection vs. seeing some code that does use this pattern tends to make things much easier to comprehend.
Code that doesn't use dependency injection
Let's take a look at a quick mock up that implements a Product, ProductRepository, and a ProductService. This code will be called from a simple console application that outputs the products to the display.
Listing 1: The model
01.
public
class
Product
02.
{
03.
public
int
Id {
get
;
set
; }
04.
public
string
Name {
get
;
set
; }
05.
public
string
Description {
get
;
set
; }
06.
public
double
Price {
get
;
set
; }
07.
}
08.
public
class
ProductRepository
09.
{
10.
public
Product[] GetProducts()
11.
{
12.
List<Product> result =
new
List<Product>();
13.
for
(
int
i = 1; i <= 10; i++)
14.
{
15.
result.Add(
new
Product()
16.
{Description =
"Product Description "
+ i, Id = i, Name =
"Product "
+ i, Price = i});
17.
}
18.
return
result.ToArray();
19.
}
20.
}
21.
public
class
ProductService
22.
{
23.
public
Product[] GetProducts(
int
Page,
int
RecordsPerPage)
24.
{
25.
Product[] result =
new
ProductRepository().GetProducts();
26.
return
result.Skip((Page - 1) * RecordsPerPage).Take(RecordsPerPage).ToArray();
27.
}
28.
}
We have a simple Product class that has an ID
, Name
, Description
, and Price
. Next we have a mocked up ProductRepository that can return a list of Products in a paged format. Now let's see the console code that outputs some products via a call to the ProductService to get a list of Products.
Listing 2: Console app
1.
static
void
Main(
string
[] args)
2.
{
3.
foreach
(Product product
in
new
ProductService().GetProducts(1,5))
4.
{
5.
Console.WriteLine(
"ID: "
+ product.Id +
" Name: "
+ product.Name);
6.
}
7.
Console.ReadLine();
8.
}
Now that we can see how this application works from a functional point of view a question comes up: How do we test this? Some might say that we can't test this but that is not technically true. Let's take a quick look at how we test non-injected code. We will start by creating a test for our ProductRepository. Given that this type of class connects to infrastructure in a real scenario this is more of an integration test than it is a unit test. But since this is a demo let's see a test that wraps around the repository.
Listing 3: Product Repository Tests
01.
[TestFixture]
02.
class
ProductRepositoryTests
03.
{
04.
[Test]
05.
public
void
GetProducts_ReturnsListOfProducts()
06.
{
07.
ProductRepository productRepository =
new
ProductRepository();
08.
Product[] products = productRepository.GetProducts();
09.
Assert.IsNotNull(products);
10.
}
11.
}
As you can see this test simply gets a list of products from the ProductRepository and tests that the returned item is not null. For an integration test this might be acceptable. But this is not a real "unit" test though as this would not test only the code in a repository method but also all of the underlying code that touches the ORM, the database, etc.
Now let's see how we can test the ProductService given that it has a strong dependency on the ProductRepository.
Listing 4: Product Service Tests
01.
[TestFixture]
02.
public
class
ProductServiceTests
03.
{
04.
[Test]
05.
public
void
GetProducts_NegativePageNumberPassed_ReturnsProducts()
06.
{
07.
Product[] products =
new
ProductService().GetProducts(-2, 5);
08.
Assert.IsNotNull(products);
09.
Assert.IsTrue(products.Length == 5);
10.
}
11.
[Test]
12.
public
void
GetProducts_UnrealPageNumberPassed_DoesntFail()
13.
{
14.
Product[] products =
new
ProductService().GetProducts(1000000000, 5);
15.
Assert.IsNotNull(products);
16.
Assert.IsNotNull(products.Length == 0);
17.
}
18.
}
The ProductService tests read a bit more like a unit test. In these tests you can see that we are testing the GetProducts
method off of the ProductService class. In the first test we are testing the state where a negative page number is passed to the method and we are still expecting the method to return some products. You can see this in that the common form of the class.method name is very clear in documenting the setup.
ClassName.MethodName_StateUnderTest_ExpectedResult
Or
ProductServiceTests.GetProducts_NegativePageNumberPassed_ReturnsProducts
This way when you run the unit tests in some form of a test runner you can easily see what is passing or failing and understand exactly what is going on with little to no additional research.
Now even though this runs and appears on the surface to be in good unit testing form...it really isn't! The reason why these tests are not good is that when we are testing our ProductRepository there is no real way to just test the repository (assuming that it actually touched a database somewhere and didn't actually spin up fake data). In the same vein our ProductService tests are also incapable of testing just the ProductService in that it has a direct dependency on the ProductRepository. This means that when we test the ProductService we are also executing code in the ProductRepository! That totally breaks the definition of a Unit Test...or testing a single unit of code.
Code that does use dependency injection
Now let's refactor this code a bit so that it follows the dependency injection pattern. To do this we first need to move any dependencies up and out of the code and into either a method as a parameter or into a constructor as a parameter. Either is technically acceptable. The loose rule here is that if more than one method in a class will need access to the dependency then put it in the constructor; otherwise put it in the method signature. We will stick to putting the dependencies into our constructor for a reason that I will discuss later.
Here is what our current code looks like now after refactoring out the dependencies.
Listing 5: Product Service
01.
public
class
ProductService
02.
{
03.
private
ProductRepository _productRepository;
04.
public
ProductService(ProductRepository productRepository)
05.
{
06.
_productRepository = productRepository;
07.
}
08.
public
Product[] GetProducts(
int
Page,
int
RecordsPerPage)
09.
{
10.
Product[] result = _productRepository.GetProducts();
11.
return
result.Skip((Page - 1) * RecordsPerPage).Take(RecordsPerPage).ToArray();
12.
}
13.
}
Notice that we now have a new private field _productRepository
of type ProductRepository and that this field is set through the constructor of the ProductService. Then when we need to use a ProductRepository we can use the _productRepository
variable.
Does this make our code more testable? No...not really. Why? ...you might ask. Although we have injected the dependency you might notice that we are still directly dependent on the class at hand. In this case the ProductService is still directly dependent on the ProductRepository.
The key behind dependency injection is not only that the dependency is injected into the method but that the dependency is also abstracted away. To do this we will create interfaces that represent our current ProductService and ProductRepository. Then we can define the dependency around the interface rather than the type itself by specifying the interface as the type to be injected. Here is how that code looks.
Listing 6: Product Service
01.
public
class
ProductService : IProductService
02.
{
03.
private
IProductRepository _productRepository;
04.
public
ProductService(IProductRepository productRepository)
05.
{
06.
_productRepository = productRepository;
07.
}
08.
public
Product[] GetProducts(
int
Page,
int
RecordsPerPage)
09.
{
10.
Product[] result = _productRepository.GetProducts();
11.
return
result.Skip((Page - 1) * RecordsPerPage).Take(RecordsPerPage).ToArray();
12.
}
13.
}
Now that the ProductService is only dependent on the interface that defines a ProductRepository we no longer need to worry about what is passed in as long as it implements the interface appropriately. This means that our code is a bit more testable now. Let's see how this changes our tests.
Listing 7: Product Service Tests
01.
[TestFixture]
02.
public
class
ProductServiceTests
03.
{
04.
[Test]
05.
public
void
GetProducts_NegativePageNumberPassed_ReturnsProducts()
06.
{
07.
MockRepository mocks =
new
MockRepository();
08.
List<Product> testData =
new
List<Product>();
09.
for
(
int
i = 0; i < 10; i++)
10.
{
11.
testData.Add(
new
Product() { Description =
"Product Description"
, Id = i, Name =
"Product Name"
, Price = 12.00 });
12.
}
13.
IProductRepository _mockRepository = mocks.StrictMock<IProductRepository>();
14.
Expect.Call(_mockRepository.GetProducts()).Return(testData.ToArray());
15.
mocks.ReplayAll();
16.
Product[] products =
new
ProductService(_mockRepository).GetProducts(-2, 5);
17.
Assert.IsNotNull(products);
18.
Assert.IsTrue(products.Length == 5);
19.
}
20.
[Test]
21.
public
void
GetProducts_UnrealPageNumberPassed_DoesntFail()
22.
{
23.
MockRepository mocks =
new
MockRepository();
24.
List<Product> testData =
new
List<Product>();
25.
for
(
int
i = 0; i < 10; i++)
26.
{
27.
testData.Add(
new
Product() { Description =
"Product Description"
, Id = i, Name =
"Product Name"
, Price = 12.00 });
28.
}
29.
IProductRepository _mockRepository = mocks.StrictMock<IProductRepository>();
30.
Expect.Call(_mockRepository.GetProducts()).Return(testData.ToArray());
31.
mocks.ReplayAll();
32.
Product[] products =
new
ProductService(_mockRepository).GetProducts(1000000000, 5);
33.
Assert.IsNotNull(products);
34.
Assert.IsNotNull(products.Length == 0);
35.
}
36.
}
You may have noticed in our new test code that we are no longer testing anything other than the ProductService. But since the ProductService does have a dependency on an IProductRepository we have to do something to provide it with a working implementation of IProductRepository. To do this we can use a tool such as RhinoMocks (or TypeMock) to create a mocked version of our IProductRepository. RhinoMocks allows you to dynamically mock out an object and then tell the framework to not only expect a call into the mocked object but also what that expected call should return.
As you can see in the above code we have had to do a bit more work to set up a test. But as expected we have not done anything more than what our tests would require. Most importantly we are not touching any code outside the bounds of what we want to test directly. In order to create a mock you generally need three things, the mocking framework reference, to define what call expected, and to define what is returned by the call. Obviously you can do more as needed but this is generally the minimum requirement. Once you have these things in place you can tell RhinoMocks to get ready for use by calling ReplayAll()
(in RhinoMocks's case any ways).
Refactoring for dependency injection
How does all of this apply to our Knowledge Exchange project? Let's identify where we have issues first. Then we can address those issues one at a time until we have an entirely testable set up.
What needs to be refactored?
There is a big difference between our PostRepository in our project and the ProductRepository we used when discussing Dependency Injection above. Primarily that difference comes in that our PostRepository actually does communicate with the infrastructure using our ORM choice LINQ to SQL. We can fix this like any other dependency by pushing it up and having the Connection injected.
The PostService object is very similar to our ProductService in that it's only dependency currently is on the PostRepository. For this reason we will need to push up the PostRepository dependency which means that we will also need to push up the Connection dependency a bit further too.
The one other major bit of code that we really should have under test is our controllers. In this case we added our logic to our HomeController that comes with the MVC framework. In order to test the Index method of our HomeController we need to somehow push up our dependency on our PostService. This, more than the other two areas, will take quite a bit more to make happen. One thing at a time though!
Lets refactor it!
In order for us to refactor our PostRepository we need to push the Connection class up and out of the PostRepository. In order to do that we will need first create an interface that represents our Connection class.
Listing 8: IConnection.cs
1.
public
interface
IConnection
2.
{
3.
KEDataContext GetContext();
4.
}
Once that is done we can then add a new parameter to our PostRepository's contructor.
Listing 9: PostRepository.cs
01.
public
class
PostRepository
02.
{
03.
private
IConnection _connection;
04.
public
PostRepository(IConnection connection)
05.
{
06.
_connection = connection;
07.
}
08.
public
List<Domain.Post> GetAllPosts()
09.
{
10.
List<Post> result =
new
List<Post>();
11.
using
(KEDataContext dc = _connection.GetContext())
12.
{
13.
result = dc.Posts.OrderByDescending(p => p.CreateDate).ToList();
14.
}
15.
return
Mapper.Map<List<DataAccess.Post>, List<Domain.Post>>(result);
16.
}
17.
}
Once this refactoring is complete we can then look to refactor our PostService. In this class we need to push up our PostRepository class to our PostService's constructor.
Listing 10: PostService.cs
01.
public
class
PostService
02.
{
03.
private
IPostRepository _postRepository;
04.
public
PostService(IPostRepository postRepository)
05.
{
06.
_postRepository = postRepository;
07.
}
08.
public
List<Domain.Post> GetAllPosts()
09.
{
10.
return
_postRepository.GetAllPosts();
11.
}
12.
}
From here we need to address our controller. It should also have its dependencies injected as well so that we can test it in the same way that we can now test our PostRepository and PostService. Setting up injection for a controller is no different than adding injection to any other class. The only problem though is that we are not directly in charge of loading and controlling the Controllers - the framework is. In order to apply injection to a Controller we will have to jump through a few hoops that we will cover in the next article.
For now we will modify our HomeController so that it can take care of our dependencies. While this means that we won't be able to test our HomeController (which means that the refactoring is not totally complete) we will be able to run our application and write some tests for the other parts of our code. We will finish this round of refactoring in the next chapter.
Writing our tests
We can start writing our tests around the PostRepository. Keep in mind that this is not really a UnitTest as much as it is an IntegrationTest. There really isn't anything in the PostRepository that can be unit tested at this particular time. And that is ok. Here is the integration test which actually goes to the database and fetches some data. In the test we simply verify that some data came back.
Listing 11: PostRepositoryTests.cs
01.
[TestFixture]
02.
public
class
PostRepositoryTests
03.
{
04.
[Test]
05.
public
void
GetAllPosts_ReturnsPosts()
06.
{
07.
AutoMapperBootStrapper.Initialize();
08.
PostRepository _postRepository =
new
PostRepository(
new
Connection());
09.
var results = _postRepository.GetAllPosts();
10.
Assert.IsNotEmpty(results);
11.
}
12.
}
Notice that in the beginning of our test we have to run the AutoMapperBootStrapper to get the mapping functionality to work in our repository. Next we create an instance of our PostRepository which takes an instance of Connection. Then we call the GetAllPosts()
method which returns a list of Posts into our results variable. Then we can run a test to check that the results list is not empty. Something not seen here and generally not seen in a standard unit test is that we also had to add an app.config file with our connection string. Being an integration test this test does reach out and touch our database.
Next we can write a test for our PostService. This class is a little different to test in that it has a dependency on the PostRepository (or IPostRepository) but it is not much different from what was covered in our initial conversation. In this test you will notice that we initialize a MockRepository object first thing. From there we generate a list of Posts for our expected result. Then we spin up a new instance of IPostRepository using the RhinoMocks framework. Next we set up the expected call and return values. Then we are ready to initialize an instance of our IPostService which we pass in the mocked PostRepository. Finally we tell the RhinoMocks framework to get ready for our tests to call into it by calling the ReplayAll()
method. Now we are ready to start our test. We set up a new list of Domain.Posts to hold our testResult which we populate by making a call to our PostService.GetAllPosts()
method. If all works well we should have a list of Domain.Post items that we can test against.
Listing 12: PostServiceTests.cs
01.
[TestFixture]
02.
public
class
PostServiceTests
03.
{
04.
[Test]
05.
public
void
GetsAllPosts_GetsPosts()
06.
{
07.
MockRepository mocks =
new
MockRepository();
08.
List<AndrewSiemer.KnowledgeExchange.Domain.Post> posts =
new
List<AndrewSiemer.KnowledgeExchange.Domain.Post>();
09.
for
(
int
i = 0; i < 10; i++) { posts.Add(
new
AndrewSiemer.KnowledgeExchange.Domain.Post() { Body =
"Post Body"
, CreateDate = DateTime.Now, LastUpdated = DateTime.Now, PostID = i + 1, ProfileID = 1, Title =
"Post Title"
}); }
10.
IPostRepository _postRepository = mocks.StrictMock<IPostRepository>();
11.
Expect.Call(_postRepository.GetAllPosts()).Return(posts);
12.
IPostService _postService =
new
PostService(_postRepository);
13.
mocks.ReplayAll();
14.
List<AndrewSiemer.KnowledgeExchange.Domain.Post> testResult = _postService.GetAllPosts();
15.
Assert.IsNotEmpty(testResult);
16.
}
17.
}
Keep in mind that these tests are pretty lame! Since this is demo-ware we don't have a whole lot of moving parts in here to test. The PostRepository does reach out to the database so that is a good test. But the PostService is pretty much a pass through set of plumbing for expansion on later. If there were more moving parts in the PostRepository we would also want to create a UnitTest for the PostRepository that doesn't go to the database but instead tests the guts of the repository itself.
Analysis
The mere fact that we now have code that can be tested means that we have made some huge headway. We do have to keep in mind that our HomeController is not yet testable. More than even that we are instantiating all of our dependencies in the HomeController as well which may be even worse. No worries though we will remedy that soon enough. This issue of our HomeController doing what it does though has added an even more painful issue to our system in that our presentation tier now has a dependency on our data access (otherwise the HomeController wouldn't know how to create an instance of the PostRepository). We will fix that in the next article too!
Take a look at our dependency graph below. For the most part things are working out just as we would expect them too. Short of the web to dataaccess issue all is going the right direction! Do take note that our DataAccess.Tests and Domain.Tests items have no usage defined as neither have anything that can be tested just yet.
Pros
Once everything can follow along with the Dependency Injection pattern we will be able to have all of our code under test. Using this pattern not only makes our code more testable but also more flexible. Once everything is dependent only on abstractions we can swap in and out whatever we like whenever we like. We will see the use and power of this the further we go.
Cons
I have never heard of a con that has popped up due to the simple implementation of Dependency Injection. Taking a dependency on an Inversion of Control container (such as StructureMap which we will introduce in the next article) may provide a performance degradation but just following this pattern by itself won't hurt us!
Comparison Chart
Table 1: Comparison Chart
Coding Concepts Yes Sorta No
Fast/Easy to develop: Can we generate the end product quickly? X
Testable: Can we write tests around the majority of the projects code? X
Flexible for refactoring: Can we easily refactor the code base to add new concepts? X
Well abstracted: Do the users of your code only know what they need too? X
Well encapsulated: Can you change the internals of code without impacting the users of that code? X
Separation of concerns? Is your code well compartmentalized and only doing what it needs to? X
DRY? Does your code follow the "Don't repeat yourself motto?" X
SOLID? Does this code comply with the SOLID principles?
S: Single Responsibility Principle - there should never be more than one reason for a class to change
O: Open Closed Principle - should be open for extension but closed for modification
L: Liskov Substitution Principle - functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it
I: Interface Segregation Principle - clients should not be forced to depend upon interfaces that they do not use
D: Dependency Inversion Principle - high level modules should not depend upon low level modules. Both should depend upon abstractions. Abstractions should not depend upon details. Details should depend upon abstractions. X
X
X
X
X
X
Swappable? Can you swap out an entire layer down the road? X
Distributable? Can you push complex processing of logical areas to a separate server easily to offload computing cycles and scale? X
Summary
In this article we have walked through a discussion of how code that does not follow the dependency injection pattern is not as testable as code that does. With an understanding of how dependency injection works and why it is important we were then able to walk through the majority of our code to refactor towards the dependency injection pattern. Once our code was refactored to implement dependency injection we were then able to write some tests around our code. We did find that towards the end of the article there were parts of our code that we do not have total control over and therefore were unable to convert it to a testable format. With these issues identified we were able to discuss some approaches to fix them.
In the next article we will discuss how we can enhance the power of the Dependency Injection pattern by implementing an Inversion of Control container. We will discuss what an IoC container can be used for and how it works. Then we will look at implementing an Inversion of Control container in our code. We will specifically implement the IoC container StructureMap. Once StructureMap is plugged in and working we will once again refactor our code to take advantage of StructureMap. And with that refactoring completed we can then address the Controller issue that we found in this article by creating a custom ControllerFactory that takes care of locating and returning a custom controller but also takes care of instantiating our dependencies in an automated fashion using StructureMap.
Introduction
In the last article we removed the dependency that our front end and middle tier code had on our data access layer. This provided us with an application that has no ties to the data access technology that is used to connect to the surrounding infrastructure. This made the application more flexible in that the data access code and repositories can be swapped out for something new. The codebase however is no more testable than it has been in all of its previous states.In this article we will address the lack of testability that our current application has. We will do this by making our application conform to the dependency injection pattern. This will allow us to push up all of our dependencies which makes our code considerably more testable than it currently is.
What is dependency injection?
Dependency Injection as defined by Wikipedia is "the process of supplying an external dependency to a software component. It is a specific form of inversion of control where the concern being inverted is the process of obtaining the needed dependency."The statement above doesn't clearly describe what this means if your head is not already thinking in this realm. For that reason seeing some code that does not use dependency injection vs. seeing some code that does use this pattern tends to make things much easier to comprehend.
Code that doesn't use dependency injection
Let's take a look at a quick mock up that implements a Product, ProductRepository, and a ProductService. This code will be called from a simple console application that outputs the products to the display.Listing 1: The model
01.
public
class
Product
02.
{
03.
public
int
Id {
get
;
set
; }
04.
public
string
Name {
get
;
set
; }
05.
public
string
Description {
get
;
set
; }
06.
public
double
Price {
get
;
set
; }
07.
}
08.
public
class
ProductRepository
09.
{
10.
public
Product[] GetProducts()
11.
{
12.
List<Product> result =
new
List<Product>();
13.
for
(
int
i = 1; i <= 10; i++)
14.
{
15.
result.Add(
new
Product()
16.
{Description =
"Product Description "
+ i, Id = i, Name =
"Product "
+ i, Price = i});
17.
}
18.
return
result.ToArray();
19.
}
20.
}
21.
public
class
ProductService
22.
{
23.
public
Product[] GetProducts(
int
Page,
int
RecordsPerPage)
24.
{
25.
Product[] result =
new
ProductRepository().GetProducts();
26.
return
result.Skip((Page - 1) * RecordsPerPage).Take(RecordsPerPage).ToArray();
27.
}
28.
}
ID
, Name
, Description
, and Price
. Next we have a mocked up ProductRepository that can return a list of Products in a paged format. Now let's see the console code that outputs some products via a call to the ProductService to get a list of Products.Listing 2: Console app
1.
static
void
Main(
string
[] args)
2.
{
3.
foreach
(Product product
in
new
ProductService().GetProducts(1,5))
4.
{
5.
Console.WriteLine(
"ID: "
+ product.Id +
" Name: "
+ product.Name);
6.
}
7.
Console.ReadLine();
8.
}
Listing 3: Product Repository Tests
01.
[TestFixture]
02.
class
ProductRepositoryTests
03.
{
04.
[Test]
05.
public
void
GetProducts_ReturnsListOfProducts()
06.
{
07.
ProductRepository productRepository =
new
ProductRepository();
08.
Product[] products = productRepository.GetProducts();
09.
Assert.IsNotNull(products);
10.
}
11.
}
Now let's see how we can test the ProductService given that it has a strong dependency on the ProductRepository.
Listing 4: Product Service Tests
01.
[TestFixture]
02.
public
class
ProductServiceTests
03.
{
04.
[Test]
05.
public
void
GetProducts_NegativePageNumberPassed_ReturnsProducts()
06.
{
07.
Product[] products =
new
ProductService().GetProducts(-2, 5);
08.
Assert.IsNotNull(products);
09.
Assert.IsTrue(products.Length == 5);
10.
}
11.
[Test]
12.
public
void
GetProducts_UnrealPageNumberPassed_DoesntFail()
13.
{
14.
Product[] products =
new
ProductService().GetProducts(1000000000, 5);
15.
Assert.IsNotNull(products);
16.
Assert.IsNotNull(products.Length == 0);
17.
}
18.
}
GetProducts
method off of the ProductService class. In the first test we are testing the state where a negative page number is passed to the method and we are still expecting the method to return some products. You can see this in that the common form of the class.method name is very clear in documenting the setup.ClassName.MethodName_StateUnderTest_ExpectedResult
Or
ProductServiceTests.GetProducts_NegativePageNumberPassed_ReturnsProducts
This way when you run the unit tests in some form of a test runner you can easily see what is passing or failing and understand exactly what is going on with little to no additional research.
Now even though this runs and appears on the surface to be in good unit testing form...it really isn't! The reason why these tests are not good is that when we are testing our ProductRepository there is no real way to just test the repository (assuming that it actually touched a database somewhere and didn't actually spin up fake data). In the same vein our ProductService tests are also incapable of testing just the ProductService in that it has a direct dependency on the ProductRepository. This means that when we test the ProductService we are also executing code in the ProductRepository! That totally breaks the definition of a Unit Test...or testing a single unit of code.
Code that does use dependency injection
Now let's refactor this code a bit so that it follows the dependency injection pattern. To do this we first need to move any dependencies up and out of the code and into either a method as a parameter or into a constructor as a parameter. Either is technically acceptable. The loose rule here is that if more than one method in a class will need access to the dependency then put it in the constructor; otherwise put it in the method signature. We will stick to putting the dependencies into our constructor for a reason that I will discuss later.Here is what our current code looks like now after refactoring out the dependencies.
Listing 5: Product Service
01.
public
class
ProductService
02.
{
03.
private
ProductRepository _productRepository;
04.
public
ProductService(ProductRepository productRepository)
05.
{
06.
_productRepository = productRepository;
07.
}
08.
public
Product[] GetProducts(
int
Page,
int
RecordsPerPage)
09.
{
10.
Product[] result = _productRepository.GetProducts();
11.
return
result.Skip((Page - 1) * RecordsPerPage).Take(RecordsPerPage).ToArray();
12.
}
13.
}
_productRepository
of type ProductRepository and that this field is set through the constructor of the ProductService. Then when we need to use a ProductRepository we can use the _productRepository
variable.Does this make our code more testable? No...not really. Why? ...you might ask. Although we have injected the dependency you might notice that we are still directly dependent on the class at hand. In this case the ProductService is still directly dependent on the ProductRepository.
The key behind dependency injection is not only that the dependency is injected into the method but that the dependency is also abstracted away. To do this we will create interfaces that represent our current ProductService and ProductRepository. Then we can define the dependency around the interface rather than the type itself by specifying the interface as the type to be injected. Here is how that code looks.
Listing 6: Product Service
01.
public
class
ProductService : IProductService
02.
{
03.
private
IProductRepository _productRepository;
04.
public
ProductService(IProductRepository productRepository)
05.
{
06.
_productRepository = productRepository;
07.
}
08.
public
Product[] GetProducts(
int
Page,
int
RecordsPerPage)
09.
{
10.
Product[] result = _productRepository.GetProducts();
11.
return
result.Skip((Page - 1) * RecordsPerPage).Take(RecordsPerPage).ToArray();
12.
}
13.
}
Listing 7: Product Service Tests
01.
[TestFixture]
02.
public
class
ProductServiceTests
03.
{
04.
[Test]
05.
public
void
GetProducts_NegativePageNumberPassed_ReturnsProducts()
06.
{
07.
MockRepository mocks =
new
MockRepository();
08.
List<Product> testData =
new
List<Product>();
09.
for
(
int
i = 0; i < 10; i++)
10.
{
11.
testData.Add(
new
Product() { Description =
"Product Description"
, Id = i, Name =
"Product Name"
, Price = 12.00 });
12.
}
13.
IProductRepository _mockRepository = mocks.StrictMock<IProductRepository>();
14.
Expect.Call(_mockRepository.GetProducts()).Return(testData.ToArray());
15.
mocks.ReplayAll();
16.
Product[] products =
new
ProductService(_mockRepository).GetProducts(-2, 5);
17.
Assert.IsNotNull(products);
18.
Assert.IsTrue(products.Length == 5);
19.
}
20.
[Test]
21.
public
void
GetProducts_UnrealPageNumberPassed_DoesntFail()
22.
{
23.
MockRepository mocks =
new
MockRepository();
24.
List<Product> testData =
new
List<Product>();
25.
for
(
int
i = 0; i < 10; i++)
26.
{
27.
testData.Add(
new
Product() { Description =
"Product Description"
, Id = i, Name =
"Product Name"
, Price = 12.00 });
28.
}
29.
IProductRepository _mockRepository = mocks.StrictMock<IProductRepository>();
30.
Expect.Call(_mockRepository.GetProducts()).Return(testData.ToArray());
31.
mocks.ReplayAll();
32.
Product[] products =
new
ProductService(_mockRepository).GetProducts(1000000000, 5);
33.
Assert.IsNotNull(products);
34.
Assert.IsNotNull(products.Length == 0);
35.
}
36.
}
As you can see in the above code we have had to do a bit more work to set up a test. But as expected we have not done anything more than what our tests would require. Most importantly we are not touching any code outside the bounds of what we want to test directly. In order to create a mock you generally need three things, the mocking framework reference, to define what call expected, and to define what is returned by the call. Obviously you can do more as needed but this is generally the minimum requirement. Once you have these things in place you can tell RhinoMocks to get ready for use by calling
ReplayAll()
(in RhinoMocks's case any ways).Refactoring for dependency injection
How does all of this apply to our Knowledge Exchange project? Let's identify where we have issues first. Then we can address those issues one at a time until we have an entirely testable set up.What needs to be refactored?
There is a big difference between our PostRepository in our project and the ProductRepository we used when discussing Dependency Injection above. Primarily that difference comes in that our PostRepository actually does communicate with the infrastructure using our ORM choice LINQ to SQL. We can fix this like any other dependency by pushing it up and having the Connection injected.The PostService object is very similar to our ProductService in that it's only dependency currently is on the PostRepository. For this reason we will need to push up the PostRepository dependency which means that we will also need to push up the Connection dependency a bit further too.
The one other major bit of code that we really should have under test is our controllers. In this case we added our logic to our HomeController that comes with the MVC framework. In order to test the Index method of our HomeController we need to somehow push up our dependency on our PostService. This, more than the other two areas, will take quite a bit more to make happen. One thing at a time though!
Lets refactor it!
In order for us to refactor our PostRepository we need to push the Connection class up and out of the PostRepository. In order to do that we will need first create an interface that represents our Connection class.Listing 8: IConnection.cs
1.
public
interface
IConnection
2.
{
3.
KEDataContext GetContext();
4.
}
Listing 9: PostRepository.cs
01.
public
class
PostRepository
02.
{
03.
private
IConnection _connection;
04.
public
PostRepository(IConnection connection)
05.
{
06.
_connection = connection;
07.
}
08.
public
List<Domain.Post> GetAllPosts()
09.
{
10.
List<Post> result =
new
List<Post>();
11.
using
(KEDataContext dc = _connection.GetContext())
12.
{
13.
result = dc.Posts.OrderByDescending(p => p.CreateDate).ToList();
14.
}
15.
return
Mapper.Map<List<DataAccess.Post>, List<Domain.Post>>(result);
16.
}
17.
}
Listing 10: PostService.cs
01.
public
class
PostService
02.
{
03.
private
IPostRepository _postRepository;
04.
public
PostService(IPostRepository postRepository)
05.
{
06.
_postRepository = postRepository;
07.
}
08.
public
List<Domain.Post> GetAllPosts()
09.
{
10.
return
_postRepository.GetAllPosts();
11.
}
12.
}
For now we will modify our HomeController so that it can take care of our dependencies. While this means that we won't be able to test our HomeController (which means that the refactoring is not totally complete) we will be able to run our application and write some tests for the other parts of our code. We will finish this round of refactoring in the next chapter.
Writing our tests
We can start writing our tests around the PostRepository. Keep in mind that this is not really a UnitTest as much as it is an IntegrationTest. There really isn't anything in the PostRepository that can be unit tested at this particular time. And that is ok. Here is the integration test which actually goes to the database and fetches some data. In the test we simply verify that some data came back.Listing 11: PostRepositoryTests.cs
01.
[TestFixture]
02.
public
class
PostRepositoryTests
03.
{
04.
[Test]
05.
public
void
GetAllPosts_ReturnsPosts()
06.
{
07.
AutoMapperBootStrapper.Initialize();
08.
PostRepository _postRepository =
new
PostRepository(
new
Connection());
09.
var results = _postRepository.GetAllPosts();
10.
Assert.IsNotEmpty(results);
11.
}
12.
}
GetAllPosts()
method which returns a list of Posts into our results variable. Then we can run a test to check that the results list is not empty. Something not seen here and generally not seen in a standard unit test is that we also had to add an app.config file with our connection string. Being an integration test this test does reach out and touch our database.Next we can write a test for our PostService. This class is a little different to test in that it has a dependency on the PostRepository (or IPostRepository) but it is not much different from what was covered in our initial conversation. In this test you will notice that we initialize a MockRepository object first thing. From there we generate a list of Posts for our expected result. Then we spin up a new instance of IPostRepository using the RhinoMocks framework. Next we set up the expected call and return values. Then we are ready to initialize an instance of our IPostService which we pass in the mocked PostRepository. Finally we tell the RhinoMocks framework to get ready for our tests to call into it by calling the
ReplayAll()
method. Now we are ready to start our test. We set up a new list of Domain.Posts to hold our testResult which we populate by making a call to our PostService.GetAllPosts()
method. If all works well we should have a list of Domain.Post items that we can test against.Listing 12: PostServiceTests.cs
01.
[TestFixture]
02.
public
class
PostServiceTests
03.
{
04.
[Test]
05.
public
void
GetsAllPosts_GetsPosts()
06.
{
07.
MockRepository mocks =
new
MockRepository();
08.
List<AndrewSiemer.KnowledgeExchange.Domain.Post> posts =
new
List<AndrewSiemer.KnowledgeExchange.Domain.Post>();
09.
for
(
int
i = 0; i < 10; i++) { posts.Add(
new
AndrewSiemer.KnowledgeExchange.Domain.Post() { Body =
"Post Body"
, CreateDate = DateTime.Now, LastUpdated = DateTime.Now, PostID = i + 1, ProfileID = 1, Title =
"Post Title"
}); }
10.
IPostRepository _postRepository = mocks.StrictMock<IPostRepository>();
11.
Expect.Call(_postRepository.GetAllPosts()).Return(posts);
12.
IPostService _postService =
new
PostService(_postRepository);
13.
mocks.ReplayAll();
14.
List<AndrewSiemer.KnowledgeExchange.Domain.Post> testResult = _postService.GetAllPosts();
15.
Assert.IsNotEmpty(testResult);
16.
}
17.
}
Analysis
The mere fact that we now have code that can be tested means that we have made some huge headway. We do have to keep in mind that our HomeController is not yet testable. More than even that we are instantiating all of our dependencies in the HomeController as well which may be even worse. No worries though we will remedy that soon enough. This issue of our HomeController doing what it does though has added an even more painful issue to our system in that our presentation tier now has a dependency on our data access (otherwise the HomeController wouldn't know how to create an instance of the PostRepository). We will fix that in the next article too!Take a look at our dependency graph below. For the most part things are working out just as we would expect them too. Short of the web to dataaccess issue all is going the right direction! Do take note that our DataAccess.Tests and Domain.Tests items have no usage defined as neither have anything that can be tested just yet.
Pros
Once everything can follow along with the Dependency Injection pattern we will be able to have all of our code under test. Using this pattern not only makes our code more testable but also more flexible. Once everything is dependent only on abstractions we can swap in and out whatever we like whenever we like. We will see the use and power of this the further we go.Cons
I have never heard of a con that has popped up due to the simple implementation of Dependency Injection. Taking a dependency on an Inversion of Control container (such as StructureMap which we will introduce in the next article) may provide a performance degradation but just following this pattern by itself won't hurt us!Comparison Chart
Table 1: Comparison Chart
Coding Concepts | Yes | Sorta | No |
---|---|---|---|
Fast/Easy to develop: Can we generate the end product quickly? | X | ||
Testable: Can we write tests around the majority of the projects code? | X | ||
Flexible for refactoring: Can we easily refactor the code base to add new concepts? | X | ||
Well abstracted: Do the users of your code only know what they need too? | X | ||
Well encapsulated: Can you change the internals of code without impacting the users of that code? | X | ||
Separation of concerns? Is your code well compartmentalized and only doing what it needs to? | X | ||
DRY? Does your code follow the "Don't repeat yourself motto?" | X | ||
SOLID? Does this code comply with the SOLID principles? S: Single Responsibility Principle - there should never be more than one reason for a class to change O: Open Closed Principle - should be open for extension but closed for modification L: Liskov Substitution Principle - functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it I: Interface Segregation Principle - clients should not be forced to depend upon interfaces that they do not use D: Dependency Inversion Principle - high level modules should not depend upon low level modules. Both should depend upon abstractions. Abstractions should not depend upon details. Details should depend upon abstractions. | X X X X X X | ||
Swappable? Can you swap out an entire layer down the road? | X | ||
Distributable? Can you push complex processing of logical areas to a separate server easily to offload computing cycles and scale? | X |
Summary
In this article we have walked through a discussion of how code that does not follow the dependency injection pattern is not as testable as code that does. With an understanding of how dependency injection works and why it is important we were then able to walk through the majority of our code to refactor towards the dependency injection pattern. Once our code was refactored to implement dependency injection we were then able to write some tests around our code. We did find that towards the end of the article there were parts of our code that we do not have total control over and therefore were unable to convert it to a testable format. With these issues identified we were able to discuss some approaches to fix them.In the next article we will discuss how we can enhance the power of the Dependency Injection pattern by implementing an Inversion of Control container. We will discuss what an IoC container can be used for and how it works. Then we will look at implementing an Inversion of Control container in our code. We will specifically implement the IoC container StructureMap. Once StructureMap is plugged in and working we will once again refactor our code to take advantage of StructureMap. And with that refactoring completed we can then address the Controller issue that we found in this article by creating a custom ControllerFactory that takes care of locating and returning a custom controller but also takes care of instantiating our dependencies in an automated fashion using StructureMap.
Subscribe to:
Posts (Atom)