Blog Stats
  • Posts - 18
  • Articles - 0
  • Comments - 17
  • Trackbacks - 92

 

Wednesday, September 20, 2006

Monday, August 28, 2006

Ruby-on-Rails Capabilities in ASP.NET

It's great to see that ASP.NET tools are finally surfacing that leverage the same code-generation capabilities as Ruby-on-Rails.  ASP.NET ActionPack (http://www.codeplex.com/Wiki/View.aspx?ProjectName=actionpack) is one such example that builds data-access and presentation scaffolding.  Like RoR, ASP.NET ActionPack will automatically build admin screens for all your basic CRUD fuctionality; unlike RoR, ASP.NET ActionPack will even look for foreign keys within your DB schema and provide drop-down options to populate those foreign key values.  What the 10-minute webcast does not show is how to add methods to a pre-generated class - I'll assume/suggest partial classes are leveraged here.  Additionally, it does not go into details concerning modifications to the presentation scaffolding.  But overall, it looks to be headed in the right direction and I look forward to seeing how it evolves.

Billy

Wednesday, August 09, 2006

Wrapping C# Events with Accessors

It is a given that private members should be wrapped with public accessors for proper encapsulation of class data.  But it is common to see people publicly declaring events, such as with public event EventHandler SomeEventExposingHimself;.  Essentially, this is the same as exposing a private member to the world without accessors, such as with public string SomeStringThatYouShouldNotHaveAccessToDirectly;.  Any subscriber listening for the event is now tied directly to the actual class member.  C# makes it easy to provide accessors for your events, just as it does for class members, with the keywords add and remove. The following is an example of an event properly wrapped with public accessors:

public event EventHandler EventModestlyExposed {

add {

someEventNotWantingToExposeHimself += value;

}

remove {

someEventNotWantingToExposeHimself -= value;

}

}

 

private event EventHandler someEventNotWantingToExposeHimself;

Billy

Thursday, July 20, 2006

Model-View-Presenter split into two "new" patterns

For the past year or so, Martin Fowler has included the pattern Model-View-Presenter, or MVP, in his upcoming addendum to  Patterns of Enterprise Application Development.  Due to apparent confusions between MVC and MVP, Fowler has now split this pattern into what he's calling “Passive View” (http://martinfowler.com/eaaDev/PassiveScreen.html) and “Supervising Controller/Presenter” (http://martinfowler.com/eaaDev/SupervisingPresenter.html).  (Now what am I to do! ;)

Passive View stresses zero/none/nada dependencies between the View and the Model.  Previously, with MVP, the View could be given a dependency to the Model to decrease the amount of communications between the View and the Presenter.  But, from how I understand it, the Controller in Passive View (previously the Presenter in MVP) would now have a dependency on System.Web, in ASP.NET anyway, to facilitate direct communications with the View display elements.  A “Test Double“ could then sit in for the View for unit testing purposes.  Although I really don't like the idea of a controller depending on System.Web, Passive View seems a bit simpler than MVP.  But instead of it depending on System.Web, Fowler suggests the use of a “Gateway“ to avoid the dependency.  The primary disadvantage to Passive View, in ASP.NET, is that it would become much more tedius to bind to a webcontrol, such as the datagrid, if the View has no knowledge of the Model.  I suppose DTOs could be used in their stead.

Alternatively, Supervising Controller looks to be a “flexible” interpretation of the original MVP pattern.  I.e. the View isn't completely dumb and knows how to use a limited amount of the Model.  Supervising Controller leaves the data binding up to the View and only helps out when the logic becomes non-trivial.  I believe this is very similar to how I discussed MVP to be in http://www.codeproject.com/useritems/ModelViewPresenter.asp.  The primary benefit to this pattern is that it makes the presentation logic easy to unit test.  The primary drawback, in my opinion, is that it makes it difficult to draw a clear line between what should go in the View (the code-behind in ASP.NET) and what should go in the Supervising Controller.  Passive View makes the separation of responsibility a bit more clear.

Now off to go update my class PPTs.

Billy

Monday, July 17, 2006

Using NHibernate with Multiple Databases

I've added a new article to CodeProject.com concerning NHibernate with multiple databases with either ASP.NET or .NET.  The article can be found at http://www.codeproject.com/useritems/NHibernateMultipleDBs.asp.  Any and all feedback is certainly welcome.

As an addendum, Hector Cruz has described an approach to connecting to multiple DBs on the same server via NHibernate HBM files at http://forum.hibernate.org/viewtopic.php?t=962161.

Billy

Monday, July 10, 2006

Converting System.Collections to System.Collections.Generic

I believe the following is the fastest way to convert a non-typed list to a strongly typed (generic) list using C# .NET:

public List ConvertToGenericList(IList listOfObjects) {
   ArrayList notStronglyTypedList = new ArrayList(listOfObjects);
   return new List(notStronglyTypedList.ToArray(typeof(T)) as T[]);
}

Note that this will fail if the non-typed collection contains anything that cannot be casted to type of T.

Please let me know if there's a more efficient way to do this!

Billy

Saturday, March 11, 2006

NHibernate Best Practices with ASP.NET, Generics & Unit Tests

I finally got around to it... the whole shebang of NHibernate best practices with ASP.NET and Generics.  The article, along with the related source, can be found at http://www.codeproject.com/useritems/NHibernateBestPractices.asp.  Your review, feedback and suggestions would be much appreciated!


3/3/06 UPDATE

I've updated the article on Code Project to include a unit testing project to show how to simulate the web context and how to create “mock” DAO objects within your unit tests.

Wednesday, March 15, 2006

The solution for proper ASP.NET MVC

Arguments abound for whether or not ASP.NET provides adequate MVC.  On the other hand, many feel Page Controller and Front Controller are the way to go.  Others feel the entire page model should be abandoned in the favor of something more attuned to Ruby on Rails such as Castle MonoRail.  For me, I've always liked the page event model and feel user and server controls are wonderful, but have struggled with making the code behind strictly part of the view.  I believe Model-View-Presenter is the answer.  The following are some great resources to learn more about the technique:

Thursday, March 30, 2006

Journeys with Model-View-Presenter and ASP.NET

On a previous post, I mentioned my introduction to Model-View-Presenter (MVP).  I've now gotten a chance to try it out on a new project and have been very pleased with the results thus far.  MVP provides an approach for clean separation of concerns within the ASP.NET presentation layer without dismissing the page event model.  MVP sees the code-behind, along with the ASPX page, as strictly part of the view and provides a patter to treat it accordingly.  Although the pattern itself is easy to understand after looking at an example, I expect it'll be another couple of years before strong MVP “best practices” emerge.  (I was surprised to find that MVP was actually conceived over ten years ago by IBM's Taligent and put to the test on Dolphin Smalltalk.  Even though it's been around for a while, it didn't get any substantial attention unitl recently with Martin Fowler's inclusion of MVP in his upcoming book.)

I'd like to put forth some rules of thumb for using MVP with ASP.NET that I've learned from a number of other sources and recent personal experiences.  These are very open to criticism...in fact, I encourage it!  By no means do I deliever these as true best practices of MVP - I hope to get as much feedback as possible concerning your own experiences and the applicability of these tips.  (I have not provided much with respect to MVP code samples since your favorite search engine can find you plenty.  The links below contain samples as well.)

MVP Tips:

  • Calls from the presenter back to the view should resolve to simple accessors; the accessors should only accept/return model objects or primitives - business objects, data transfer objects, datasets, etc.  (http://codebetter.com/blogs/jeremy.miller/archive/2006/02/01/137457.aspx)
  • The presenter constructor should accept the view it presents along with any services it may depend on (i.e. dependency injection).  The following example serves to illustrates:

private readonly IEditCommentView view;
private readonly ICommentDao commentDao;

public EditCommentPresenter(IEditCommentView view, ICommentDao commentDao) {
  this.view = view;
  this.commentDao = commentDao;
}

  • The presenter should never require a reference to System.Web.
  • Don't expose too much of how the view is implemented via its interface.  For instance, examine the following code...

public bool IsClassical {
  get { … }
  set {
    chkClassical.Checked = value;
    txtComposer.Enabled = value;
  }
}

In the above example, you could instead provide two setters on the view:  IsClassical and ComposerEnabled.  The downside to having two setters is that you've bound a very minor implmenation detail to the interface - arguably, you should be able to easily switch concrete views and have presentation variations among them all.  The counter-point is that the view should remain completely ignorant of business decisions and should leave all details up to the presenter; therefore, the view should have two setters:  IsClassical and ComposerEnabled.  Additionally, giving ComposerEnabled its own setter allows it to be disabled for security reasons; regardless of the other settings.  (This example and discussion was brought up at http://codebetter.com/blogs/ben.reichelt/archive/2005/11/18/learning_model_view_presenter.aspx.)  Personally, I've found the single setter to be cleaner and promotes a more cohesive interface.

  • It's common practice to partition the GUI into separate user controls for proper separation of concerns and maintainability.  An effect of this is that it becomes easy to define the view/presenter relationship from the code-behind of the containing ASPX page.  The following example illustrates the parent page determining this relationship between a contained usercontrol (i.e. the view defined as commentListing), and the usercontrol's presenter (ListCommentsPresenter):

ListCommentsPresenter presenter = new ListCommentsPresenter(commentListing, DaoFactory.GetCommentDao());
commentListing.AttachPresenter(presenter);

if (!IsPostBack) {
  presenter.Init();
}

The call to AttachPresenter binds the presenter to a private member within the user control.  With this approach, the usercontrol never has to know how to create the presenter nor need knowledge of the constructor arguments that go along with the presenter's creation.  Finally, the usercontrol doesn't have to worry about when to call Init.  (This implementation tip comes from http://codebetter.com/blogs/jeremy.miller/archive/2006/02/01/137457.aspx.)

  • Views should provide a DisplayMessage property to the presenter so as to return feedback concerning the execution of an operation.  Alternatively, the presenter could return a “presenter result“ object to indicate what should happen next:  redirect, stay on the page, go to login, etc.  (This latter tip came from Mike Mason's blog that's accessible via Google cache.)
  • Unit tests should be used for guiding the communications protocol between a view and presenter.  Implementing the view itself should always be the last thing you do - NUnit and FitNesse can be used to validate most of the presentation before writing a scratch of HTML.  The primary benefit of this is ensuring you've done a good job of cleanly separating all possible business logic out of the view.

There are certainly other topics of discussion concerning MVP, but the above should be a good start with respect to “better“ MVP practices.  Please send feedback, comments and criticisms my way!

Billy

Sunday, July 02, 2006

Model-View-Presenter with ASP.NET: An (almost) exhaustive examination

I've been working on an article for the past few weeks concerning the usage of the Model-View-Presenter pattern with ASP.NET.  The article has been completed and uploaded to http://www.codeproject.com/useritems/ModelViewPresenter.asp.  I hope you find this article useful.  Please feel free to raise your questions and/or concerns.

Billy

Wednesday, May 10, 2006

Using NUnitAsp to test a secure webpage

NUnitAsp is a great tool for unit testing ASP.NET web pages.  Although NUnitAsp tests are slow to run, they're especially useful for running “web smoke tests” on a nightly basis.  (I mark every NUnitAsp class with [Category("Web Smoke Tests")] so that I can easily exclude them from my more frequent unit testing.)  On many projects, authentication is required to view a webpage.  When testing an application requiring Windows authentication, NUnitAsp can be easily configured to run as the current user logged in or as a specific domain user.

The sample test below shows how to run an NUnitAsp test using the credentials of the user that's currently logged in:

[Test]

public void TestProjectScope() {

Browser.Credentials = System.Net.CredentialCache.DefaultCredentials;

Browser.GetPage("http://localhost/WebPageToTest.aspx");

}

The sample test below shows how to run an NUnitAsp test using specific credentials.  If you're expecting the unit tests to be run from different computers, this is the recommended approach so that the tests are always run as the same person for consistency:

[Test]

public void TestProjectScope() {

Browser.Credentials = new NetworkCredential("username", "password", "domain");

Browser.GetPage("http://localhost/WebPageToTest.aspx");

}

Note that the username/password/domain must represent actual credentials - the user must really exist.

Billy

Wednesday, February 15, 2006

Generic DAO with NHibernate

4/28/06 Update: The NHibernate codeproject.com article wins ASP.NET article of the month. Woohoo!

3/14/06 Update: See how this is used in a sample application at http://www.codeproject.com/useritems/NHibernateBestPractices.asp.

 


 

Hibernate.org has a great article on creating a generic DAO for Hibernate in Java. Below is what I use for the C# port.

 

The interface for common CRUD functionality...

 

public interface GenericDAO {

T GetById(IdDataType id, bool shouldLock);

List GetAll();

List GetByExample(T exampleInstance, string[] propertiesToExclude);

T SaveOrUpdate(T entity);

void Delete(T entity);

}

 

The generic DAO implementation...

 

public abstract class GenericNHibernateDAO : GenericDAO

{

/// Could be set using contruction injection IoC

public GenericNHibernateDAO(ISessionManager sessionManager) {

this.sessionManager = sessionManager;

}

 

public T GetById(IdDataType id, bool shouldLock) {

ISession session = GetSession();

T entity;

 

if (shouldLock) {

entity = (T) session.Load(persitentType, id, LockMode.Upgrade);

}

else {

entity = (T) session.Load(persitentType, id);

}

 

return entity;

}

 

public List GetAll() {

return GetByCriteria();

}

 

protected List GetByCriteria(params ICriterion[] criterion) {

ISession session = GetSession();

ICriteria criteria = session.CreateCriteria(persitentType);

foreach (ICriterion criterium in criterion) {

criteria.Add(criterium);

}

GenericUtils genericUtils = new GenericUtils();

return genericUtils.ConvertToGenericList(criteria.List());

}

 

public List GetByExample(T exampleInstance, string[] propertiesToExclude) {

ISession session = GetSession();

ICriteria criteria = session.CreateCriteria(persitentType);

Example example = Example.Create(exampleInstance);

 

foreach (string propertyToExclude in propertiesToExclude) {

example.ExcludeProperty(propertyToExclude);

}

 

criteria.Add(example);

 

GenericUtils genericUtils = new GenericUtils();

return genericUtils.ConvertToGenericList(criteria.List());

}

 

public T SaveOrUpdate(T entity) {

ISession session = GetSession();

session.SaveOrUpdate(entity);

 

return entity;

}

 

public void Delete(T entity) {

ISession session = GetSession();

session.Delete(entity);

}

 

private ISession GetSession() {

Check.Require(sessionManager != null, "sessionManager was not set");

return sessionManager.OpenSession();

}

 

private Type persitentType = typeof(T);

private ISessionManager sessionManager;

}

 

And for using this within your code...

 

public class ProjectDAONHibernate : GenericNHibernateDAO<Project, int> {

public ProjectDAONHibernate(ISessionManager sessionManager) : base(sessionManager) {}

}

 



Notes:

NHibernate Generics: To use generics with NHibernate, use the “NHibernate Generics” assembly available at http://www.ayende.com/projects/nhibernate-query-analyzer/generics.aspx.

SessionManager: To help with NHibernate session management, a good tool of choice is Castle Project's NHibernate facility:  http://www.castleproject.org/index.php/Facility:NHibernate.  Alternatively, a good design is explained in Chapter 8 of Hibernate In Action by Christian Bauer and Gavin King.  (They should be having a second edition coming out soon.)  The beneift of using Castle Project comes to light when used in conjunction with their Transaction factility; the Transaction facility allows you to mark which actions should be transactional via inline attributes.

Design by Contract:  You may have noticed Check.Require reference.  This is a completely optional, design-by-contract constraint using the VERY light weight framework described at http://www.codeproject.com/csharp/designbycontract.asp.

I've had wonderful success with NHibernate in the past and can continue to embrace it with C# 2.0 using generics.  The .NET community is finally starting to take notice of ORM tools like NHibernate which are helping to shave weeks, if not months, off of development.  I hope you all experience similar successes.

Tuesday, April 25, 2006

ReSharper 2.0 Beta Now Available!

After using it for a couple of hours it looks stable and ready for use.  Needless to say, it's nice to have it back in VS 2005 since the out-of-the-box refactoring support freezes the IDE 1/2 the time and takes at least a minute to complete the other 1/2 of the time.  (I can finally get rid of all those extra C# using statements just taking up space!)

When you install ReSharper 2.0, it forces you to install to VS 2005 hotfixes.  I'm not sure what happened after installing these hotfixes, but my ASP.NET solution compile times have gone from 1-2 minutes down to 10 seconds or so.  Whatever the cause, needless to say, I'm happy with the results.

You can download the beta at http://www.jetbrains.com/resharper/beta20.html.

Billy

Monday, April 24, 2006

An alternative to "placeholder" Inheritance Mapping with NHibernate

Suppose you have a “Project” object that has 0 or more “Attachment” objects in your domain.  (The Project class exposes an IList of Attachments and the Attachment has a reference to “ParentProject.”)  Now you'd like to introduce a new object called “Cabinet” which can also have a number of attachments associated with it.  (Cabinet also exposes an IList of Attachments.)  The question is, how do we manage the relationship via NHibernate and within the database so the attachment can be used by either Project or Cabinet and how does this affect the existing, one-to-many relationship between Project and Attachment?

To solve the problem you can

  1. Create subclasses, “ProjectAttachment” and “CabinetAttachment,“ and use the inheritance-mapping-strategy table-per-hierarchy using a discriminator.  You'd then change the Attachment listing within Project to contain ProjectAttachment objects.
  2. Create subclasses and use the inheritance-mapping-strategy table-per-subclass.  This ends up with three tables.  You'd also have to change the Project-Attachment as show in the first option.
  3. Create subclasses and use table-per-concrete-class.  This ends up with two tables.  You'd also have to change the Project-Attachment as show in the first option.
  4. Don't subclass Attachment but create two many-to-many join tables:  one between Project and Attachment and one between Cabinet and Attachment.

The first three options, along with their benefits and limitations, are discussed at http://www.hibernate.org/hib_docs/nhibernate/html/inheritance.html.  The forth is a simple trick to avoid having to create container subclasses that do nothing but act as a relationship place-holder for the Project-Attachment and Cabinet-Attachment relationships.  Obviously, if ProjectAttachment has different behavior than CabinetAttachment, then subclassing is the best solution.  But in many cases, you simply want the same object (e.g. Attachment) to be available to differen parent objects (e.g. Project and Cabinet).  In these cases, creating many-to-many relationships using join tables and maintaining the relationship from the parent object keeps the domain model devoid of place-holder classes that may otherwise clutter the code.

Billy

Tuesday, April 18, 2006

Dependency Injection for Loose Coupling

This post describes the use of Inversion-of-Control, or Dependency Injection, to promote loose
coupling and convenient unit testing.

----

Introduction

In designing an object-oriented application, a major tenant of design is "loose coupling." Loosely, no mean for the pun, "loose coupling" means that objects should only have as many dependencies as is needed to do their job - and the dependencies should be few. Furthermore, an object's dependencies should be on interfaces and not on "concrete" object when possible. (A concrete object is any object created with the keyword new.) Loose coupling promotes greater reusability, easier maintainability, and allows you to easily provide "mock" objects in place of expensive services, such as a socket-communicator.

"Dependency Injection" (DI), also more cryptically known as "Inversion of Control" (IoC), can be used as a technique for encouraging this loose coupling. There are two primary approaches to implementing DI: constructor injection and setter injection. Obviously, at some point, something must be responsible for creating the concrete objects that will be injected into another object. The injector can be a parent object, which I'll call the "DI controller," or can be externalized and handled by a "DI container" framework. What follows is a brief overview of the various approaches for using dependency injection techniques.

Constructor Injection

Constructor Injection is the DI technique of passing an object's dependencies to its constructor. The below example includes a class, Customer, that exposes a method for retrieving every sales-order that the customer made on a particular date. Consequently, the Customer class needs a data-access object for communicating with the database. Assume an OrderDao ("order data-access object") exists which implements the interface IOrderDao. One way that a Customer object can get this dependency is by executing the following within the : IOrderDao orderDao = new OrderDao();. The primary disadvantage of this is two-fold: 1) the benefit of having the interface in the first place has been negated since the concrete instance was created locally, and 2) OrderDao cannot easily be replaced by a mock object for testing purposes. (Mock objects will be discussed shortly.) The aforementioned example follows:

public class Customer {
    public Customer(IOrderDao orderDao) {
        if (orderDao == null) throw new ArgumentNullException("orderDao may not be null");
        
        this.orderDao = orderDao;
    }
    
    public IList GetOrdersPlacedOn(DateTime date) {
        ... code that uses the orderDao member get orders from the datasource ...
    }
    
    private IOrderDao orderDao;
}

In the example, note that the constructor accepts an interface; it DOES NOT accept a concrete object. Also note that an exception is thrown if the orderDao parameter is null. This emphasizes the importance of receiving a valid dependency. Constructor Injection is, in my opinion, the preferred mechanism for giving an object its dependencies. It is clear to the developer invoking the object which dependencies need to be given to the Customer object for proper execution. But consider the following example... Suppose you have a class with 10 methods that have no dependencies but you're adding a new method that does have a dependency on IOrderDao. You could change the constructor to use Constructor Injection, but this may force you to change constructor calls all over the place. Alternatively, you could just add a new constructor that takes the dependency, but then how does a developer easily know when to use one constructor over the other. Finally, if the dependency is very expensive to create, why should it be created and passed to the constructor when it may only be used rarely? "Setter Injection" is another DI technique that can be used in situations such as this.

Setter Injection

Setter Injection does not force dependencies to be passed to the constructor. Instead, the dependencies are set onto public properties exposed by the object in need. As implied previously, the primary motivators for doing this include 1) supporting dependency injection without having to modify the constructor of a legacy class and 2) allowing expensive resources or services to be created as late as possible and only when needed.

The code below modifies the Constructor Injection example to use Setter Injection instead:

public class Customer {
    public Customer() {}

    public IOrderDao OrderDao {
        set { orderDao = value; }
        get {
            if (orderDao == null) throw new MemberAccessException("orderDao has not been initialized");
            return orderDao;
        }
    }
    
    public IList GetOrdersPlacedOn(DateTime date) {
        ... code that uses the OrderDao public property to get orders from the datasource ...
    }
    
    // Should not be called directly; use the public property instead
    private IOrderDao orderDao;
}

In the above example, the constructor accepts no arguments. Instead, the invoking object is responsible for setting the IOrderDao dependency before the method GetOrdersPlacedOn is called. With Constructor Injection, an exception was thrown if the dependency was not set immediately; i.e. upon creation. With Setter Injection, an exception isn't thrown until a method actually attempts to use the dependency. Make note of the fact that GetOrdersPlacedOn uses the public OrderDao property; it does not call the private orderDao directly. This is so that the getter method has an opportunity to validate if the dependency has yet been initialized.

Setter Injection should be used sparingly in place of Constructor Injection because it 1) does not make it clear to the developer which dependencies are needed when, at least until a "has not been initialized" exception is thrown, and 2) makes it a bit more difficult to track down where the exception came from and why it got thrown. With this said, Setter Injection can save on modifying a lot of legacy code when introducing new methods and can provide a performance boost if the dependency is expensive or not easily accessible.

The Injectors

The next logical question is, what actually creates the dependencies that are to be injected into "injectees"? There are two appropriate places for adding creation logic: controllers and containers.

DI Controllers

The "DI controller" approach is the simpler to understand and implement. In a properly tiered architecture, an application has distinct layers for handling logic. The simplest layering usually consists of a data-layer for talking to the database, a presentation-layer for displaying the UI, a domain-logic layer for performing business logic. A "controller" layer always exists, even if not well defined, for coordinating UI events to the domain and data layers and vice versa. For example, in ASP.NET, the code-behind page acts as a rudimentary controller layer. More formalized controller-layer approaches exist: Struts and Spring for Java; Front Controller and Spring .NET for .NET. All of these approaches follow some form of variant of the Model-View-Controller pattern. Regardless of what you use as your controller, the controller is an appropriate location for performing Dependency Injection "wiring." This is where concrete objects are created and injected as dependencies. What follows are two examples of DI performed by a controller. The first is an illustrative example of "production code" - code that you'd end up deploying. The second is an example of "test code" - code that's used to test the application but is not deployed and does not have need to have a live database.

Controller code performing the dependency injection (e.g. from an ASP.NET code behind page):

... code performed when the controller is loaded ...

IOrderDao orderDao = new OrderDao();
// Using Setter Injection on a pre-existing customer
someCustomer.OrderDao = orderDao;
IList ordersPlacedToday = someCustomer.GetOrdersPlacedOn(DateTime.Now);

...

Unit-test code performing the dependency injection:

IOrderDao orderDao = new MockOrderDao();
// Using Setter Injection on a pre-existing customer
someCustomer.OrderDao = orderDao;
IList ordersPlacedToday = someCustomer.GetOrdersPlacedOn(DateTime.Now);

One of the major benefits of using a DI-controller to inject dependencies is that it's straight forward and easy to point to where the creation is occurring. The drawback to using DI-controllers is that the dependencies are still hard-coded somewhere; albeit, they're hard-coded in a location that is often subject to frequent change anyway. Another drawback is that now the DI-controllers themselves can't be easily unit-tested with mock objects. (Granted, a powerful tool such as TypeMock can do just about anything when it comes to injecting mock objects.)

In ASP.NET, I prefer to use the Model-View-Presenter (MVP) pattern and have the ASP.NET code-behind page create dependencies and inject them to the presenter via Construction Injection. Additionally, I use UserControls as the View part of the pattern so the ASP.NET code-behind acts purely as an MVP "dependency initializer" between the UserControls (view) and their presenters.

Another option to implementing constructor or setter DI is the use of an application container...

DI Containers

Inversion-of-Control/Dependency-Injection "containers" can be used to watch an application and inject dependencies whenever a particular event occurs. For example, whenever a Customer instance is created, it automatically gets injected with its needed dependencies. It's a strange concept at first, but can be useful for managing large applications with many service dependencies. Different container provides each have their own mechanism for managing dependency injection settings.

Spring .NET allows you to define dependency injections within an XML file. The following example Spring .NET XML uses Setter Injection to give an ASPX code-behind page its data-access object dependency:

<spring>
    <context type="Spring.Context.Support.WebApplicationContext, Spring.Web">
        <resource uri="config://spring/objects" />
    </context>

    <objects xmlns="http://www.springframework.net">
        <!-- Data Access Object that will be injected into ASPX page -->
        <object id="daoFactory" type="MyApp.Data.DaoFactory, MyApp.Data" />

        <object type="ViewDetails.aspx">
            <property name="DaoFactory"  ref="daoFactory" />
        </object>
    </objects>
</spring>

The ASPX code-behind simply exposes a public property called DaoFactory that "catches" the dependency whenever the page gets called. See Spring .NET's website for more details and more examples. For Java developers, be sure to check out Spring's website.

Many other containers exist, some of which don't require much XML management at all (for those of you that cringe at the sight of a 500 line XML file). For Java developers, take a look at http://www.picocontainer.org/4.1+Container+Comparison for a good comparison of options. For .NET developers, the decision is simpler as fewer options exist. (Is that a good thing?) See http://csharp-source.net/open-source/containers for some open-source options.

Unit Testing with Injected Mock Objects

The greatest benefits that I've experienced using DI are cleaner unit testing and greater portability. Portability is a given as most of the dependencies are on interfaces. But let's look at how DI can benefit unit testing as well. It is often the case that developers write unit tests against a live database. This is all well and fine, but it quickly brings the speed of a suite of unit tests to a crawl. To keep unit testing from becoming a drag, it needs to be easy to turn off slow unit tests that actually hit the database while still testing the business logic that depends on data access. Mock objects are perfect for doing just this. A mock object simulates the responses of an actual object, acting as if it's using a real resource. They're great for mocking accessing to a database, mocking calls to IO, mocking calls to a web service, etc.

The below code shows a mock data-access implementation of the IOrderDao interface used throughout the article:

public class MockOrderDao : IOrderDao {
    public Order GetOrderById(long orderId) {
        Order foundOrder = new Order();
        foundOrder.SaleDate = "1/1/06";
        foundOrder.ID = orderId;
        
        return foundOrder;
    }
}

This trivial mock data-access object implements IOrderDao and can therefore be passed to any object that's dependent on IOrderDao via Constructor or Setter injection. Now all your business logic can be tested without actually hitting the database. In my own test suite, I usually have a section that contains "real" database tests and then pass mock database-access objects for testing my domain objects.

Additional References

* http://www.martinfowler.com/articles/injection.html
* http://www-128.ibm.com/developerworks/library/j-mocktest.html

 

 

Copyright © Billy McCafferty