My code will reference Microsoft Unity but I am sure it is pretty applicable to all DI frameworks. If you're using DI correctly you never need to call new BusinessObject(new dataContext) the DI association will handle it all for you.
My example will be a little bit long since I will paste in some code I use for running a Model View Presenter website fully DI loaded by Unity. (If you want the full source check out my blog and download it from my Assembla SVN server)
Load the container (can be in code like I prefer or using configuration)
protected void Application_Start(object sender, EventArgs e)
{
Application.GetContainer()
// presenters / controllers are per request
.RegisterType<IEmployeeController, EmployeeController>(new ContextLifetimeManager<IEmployeeController>())
//Data Providers are Per session
.RegisterType<IEmployeeDataProvider, EmployeeDataProvider>(new SessionLifetimeManager<IEmployeeDataProvider>())
//Session Factory is life time
.RegisterType<INHibernateSessionManager, NHibernateSessionManager>(new ContainerControlledLifetimeManager());
}
Custom HTTP module calls Unity BuildUp Method for each page during the OnPreRequest invocation.
private static void OnPreRequestHandlerExecute(object sender, EventArgs e)
{
var handler = HttpContext.Current.Handler;
HttpContext.Current.Application.GetContainer().BuildUp(handler.GetType(), handler);
// User Controls are ready to be built up after the page initialization is complete
var page = HttpContext.Current.Handler as Page;
if (page != null)
{
page.InitComplete += OnPageInitComplete;
}
}
Page container presenter decorated with [Dependency] attribute
public partial class Employees : Page, IEmployeeView
{
private EmployeePresenter _presenter;
[Dependency]
public EmployeePresenter Presenter
{
set
{
_presenter = value;
_presenter.View = this;
}
}
}
Presenter with InjectionConstructor method
public class EmployeePresenter : Presenter<IEmployeeView>
{
private readonly IEmployeeController _controller;
[InjectionConstructor]
}
public EmployeePresenter(IEmployeeController controller)
{
_controller = controller;
}
Controller follows suit
public class EmployeeController : IEmployeeController
{
private readonly IEmployeeDataProvider _provider;
[InjectionConstructor]
public EmployeeController(IEmployeeDataProvider DataProvider)
{
_provider = DataProvider;
}
}
Same with provider
public class EmployeeController : IEmployeeController
{
private readonly IEmployeeDataProvider _provider;
[InjectionConstructor]
public EmployeeController(IEmployeeDataProvider DataProvider)
{
_provider = DataProvider;
}
}
Lastly the session manager, which contains only a regular constructor.
public class NHibernateSessionManager : INHibernateSessionManager
{
private readonly ISessionFactory _sessionFactory;
public NHibernateSessionManager()
{
_sessionFactory = GetSessionFactory();
}
}
So what happens when a page request is started the BuildUp() method is called on the page by the HttpModule. Unity then sees the Property marked with the Dependency attribute and will check it's container to see if inside it exists an EmployeePresenter object.
Since there is no such object in the container it will then try to create an EmployeePresenter. Upon inspection to create the class it sees inside the Presenter it requires a constructor that needs a IEmployeeController injected into it. Since the container actually has a manager for the controller it will see if an instance of it exists in the container which on the beginning of the page request doesn't exist, so it will go to instantiate the controller.
Unity will then see the controller requires a IEmployeeDataProvider injected into it, and it will continue on this process until it finally gets to the point where the Provider needs the session manager injected. Since the session manager has no more need for injection Unity will then create an instance of the session manager store it in the container for it's given ContainerLifeTimeManager, inject it into the Provider and store that instance, and so on down to where it finished creating a EmployeePresenter dependency for the page.