Skip to content

Instantly share code, notes, and snippets.

@NeilRobbins
Created October 15, 2012 16:11
Show Gist options
  • Save NeilRobbins/3893335 to your computer and use it in GitHub Desktop.
Save NeilRobbins/3893335 to your computer and use it in GitHub Desktop.
Example of container free DI with ASP.NET MVC
public class MvcApplication : System.Web.HttpApplication
{
// Everthing else...
protected void Application_Start()
{
// Everthing else...
ControllerBuilder.Current.SetControllerFactory(new CustomControllerFactory(new BuildControllers()));
}
}
public class CustomControllerFactory : DefaultControllerFactory
{
private readonly IBuildControllers controllerBuilder;
public CustomControllerFactory(IBuildControllers controllerBuilder)
{
this.controllerBuilder = controllerBuilder;
}
protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType)
{
if (controllerType == null)
throw new HttpException(404, string.Format("Controller was not found"));
return controllerBuilder.FetchFromCache(controllerType);
}
}
public class BuildControllers : IBuildControllers
{
private readonly IDictionary<Type, Func<IController>> controllerRegister;
public BuildControllers()
{
// If anything in here got too complex, then clearly like any other code, you'd refactor and extract.
// The following are application scoped, because this is called at application start
var barConnectionString = ConfigurationManager.ConnectionStrings["Default"].ConnectionString;
var barConnection = new SqlConnection(barConnectionString);
var barService = new Lazy<BarService>(() => new BarService(barConnection));
// Anything newed in a func will be unique for each invocation of that func, so will be request scoped like the controller
// Give objects objects with longer lifetimes, but not shorter ones, as an object will live as long as a reference is held to it
controllerRegister =
new Dictionary<Type, Func<IController>>
{
{typeof (FooController), () => new FooController()}, // With no args
{typeof (HomeController), () => new HomeController(new FizzCalculator())}, // With one, request scoped arg
{typeof (BazController), () => new BazController(barService.Value)}, // With one, application scoped arg
};
}
public IController FetchFromCache(Type typeOfControllerToBuild)
{
try
{
return controllerRegister[typeOfControllerToBuild]();
}
catch (Exception)
{
throw new HttpException(404, string.Format("Controller of type {0} cannot be built.", typeOfControllerToBuild.FullName));
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment