Last active
December 26, 2015 18:58
-
-
Save jpoehls/7197702 to your computer and use it in GitHub Desktop.
Basic ASP.NET MVC controller / data layer interaction architecture example.
This file contains hidden or 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
class GadgetController : Controller { | |
// Each MVC controller has a complementing '*ControllerContext' class. | |
private readonly IGadgetControllerContext _context; | |
GadgetController() | |
: this(new GadgetControllerContext()) { } | |
// Unit testing ctor. Allows passing in mock repositories. | |
GadgetController(IGadgetControllerContext context) { | |
_context = context; | |
} | |
ActionResult Index() { | |
ViewData["gadgets"] = _context.GadgetRepo.GetAll(); | |
return View(); | |
} | |
} |
This file contains hidden or 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
// Controller Context class for the Gadget controller. | |
// Provides access to the data repositories needed by the controller. | |
// Inherits from the base MyAppControllerContext which provides | |
// the underlying data context / session / connection stuff. | |
class GadgetControllerContext : MyAppControllerContext, IGadgetControllerContext { | |
private readonly IGadgetRepository _gadgetRepo; | |
GadgetControllerContext() { | |
_gadgetRepo = new GadgetRepository(base.DbSession); | |
} | |
IGadgetRepository GadgetRepo { get { return _gadgetRepo; } } | |
} |
This file contains hidden or 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
// Data access repository for Gadgets. | |
// Follows the repository pattern, for better or worse. | |
class GadgetRepository : IGadgetRepository { | |
// TODO: Replace IDbSession with your DataContext or whatever. | |
private readonly IDbSession _session; | |
GadgetRepository(IDbSession session) { | |
_session = session; | |
} | |
IEnumerable<Gadget> GetAll() {} | |
} |
This file contains hidden or 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
interface IGadgetControllerContext { | |
IGadgetRepository GadgetRepo { get; } | |
} |
This file contains hidden or 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
interface IGadgetRepository { | |
IEnumerable<Gadget> GetAll; | |
} |
This file contains hidden or 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
// Base class for all *ControllerContext classes. | |
// Handles opening/closing the underlying data connections/sessions/etc. | |
class MyAppControllerContext { | |
// TODO: Replace IDbSession with your DataContext or whatever. | |
IDbSession DbSession { get { return GetSessionForHttpContext(HttpContext.Current); } } | |
// TODO: This is also a great place for things like AppSettings, etc. | |
/// <summary> | |
/// Gets a per-request database unit of work session | |
/// </summary> | |
/// <author>Joshua Poehls</author> | |
public static IDbSession GetSessionForHttpContext(HttpContext ctx) | |
{ | |
return GetSessionForHttpContext(new HttpContextWrapper(ctx)); | |
} | |
private const string DbContextHttpContextItemKey = "MyAppControllerContext.DbSession"; | |
/// <summary> | |
/// Gets a per-request database unit of work session | |
/// </summary> | |
/// <author>Joshua Poehls</author> | |
public static IDbSession GetSessionForHttpContext(HttpContextBase ctx) | |
{ | |
Debug.Assert(ctx != null); | |
if (!ctx.Items.Contains(DbContextHttpContextItemKey)) | |
{ | |
var dbCtx = new MyAppDbContext(); | |
ctx.Items.Add(DbContextHttpContextItemKey, dbCtx); | |
if (DbSessionInit != null) | |
{ | |
DbSessionInit(dbCtx, new DbSessionInitEventArgs(dbCtx)); | |
} | |
} | |
return (MyAppDbContext)ctx.Items[DbContextHttpContextItemKey]; | |
} | |
// TODO: Call DisposeSessionForHttpContext() on Application.EndRequest! | |
// The MyAppControllerContextModule HttpModule does this for you if you wire it up. | |
/// <summary> | |
/// Disposes any DB context that was created for the | |
/// given <see cref="HttpContext"/>. | |
/// </summary> | |
/// <author>Joshua Poehls</author> | |
public static void DisposeSessionForHttpContext(HttpContext ctx) | |
{ | |
Debug.Assert(ctx != null); | |
if (ctx.Items.Contains(DbContextHttpContextItemKey)) | |
{ | |
var db = (MyAppDbContext)ctx.Items[DbContextHttpContextItemKey]; | |
if (db != null) | |
{ | |
db.Dispose(); | |
} | |
ctx.Items.Remove(DbContextHttpContextItemKey); | |
} | |
} | |
} |
This file contains hidden or 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
/// <summary> | |
/// Handles disposing the <see cref="MyAppControllerContext"/> object's session when the request ends. | |
/// </summary> | |
/// <author>Joshua Poehls</author> | |
public class MyAppControllerContextModule : IHttpModule | |
{ | |
public void Init(HttpApplication context) | |
{ | |
context.EndRequest += Application_EndRequest; | |
} | |
private static void Application_EndRequest(object sender, EventArgs e) | |
{ | |
var app = (HttpApplication)sender; | |
MyAppControllerContext.DisposeSessionForHttpContext(app.Context); | |
} | |
public void Dispose() { } | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment