Created
October 15, 2012 16:11
-
-
Save NeilRobbins/3893335 to your computer and use it in GitHub Desktop.
Example of container free DI with ASP.NET MVC
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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