I am doing a massive overhaul on a custom CMS that I am writing in MVC5. This custom CMS has "pages" that have "urls" stored in a database. For instance if a user requested /stackoverflow in the browser and there was a page in the database with /stackoverflow listed as the url, then I am serving the database content at the specificed CoreCms/Index Controller and view with the database content as a model property. The idea is that I can use this single controller/view to serve up any page in the database.
The rewrite that I am working uses dependency injection and async calls only in the service layer. It seems that I am having a bit of trouble with the RouteConfig RegisterRoutes static method.
Here's some code...
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.IgnoreRoute("FileBrowser/{pathInfo}");
routes.MapRoute(
name: "CmsRoutes",
url: "{*permalink}",
defaults: new { controller = "CmsCorePage", action = "Index" },
constraints: new { url = new CmsCoreRouting() }
);
routes.MapRoute(
name: "ArticlesCategoryRoute",
url: "Articles/{categoryURL}",
defaults: new { controller = "CmsCoreArticles", action = "Index", categoryURL = UrlParameter.Optional }
);
routes.MapRoute(
name: "ArticlesPostsRoute",
url: "Articles/{categoryURL}/{postURL}",
defaults: new { controller = "CmsCoreArticles", action = "ArticlePost", categoryURL = UrlParameter.Optional, postURL = UrlParameter.Optional }
);
routes.MapMvcAttributeRoutes();
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
Note that I am rewriting old code and the constraints: new { url = new CmsCoreRouting() } is code that I intend on altering here I believe.
For reference, here is the CmsCoreRouting class...
public class CmsCoreRouting : IRouteConstraint
{
private ICoreCmsServices _coreSvc;
public CmsCoreRouting()
{
}
public CmsCoreRouting(ICoreCmsServices coreSvc)
{
_coreSvc = coreSvc;
}
public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
{
if (httpContext?.Request?.FilePath == null) { return false; }
string myURL = httpContext.Request.FilePath;
if (myURL.StartsWith("/"))
{
myURL = myURL.Substring(1, myURL.Length - 1);
}
myURL = myURL.ToLower();
var siteId = CoreCms.Core.Settings.CoreCmsSettings.SiteId;
var cmsPage = AsyncUtility.RunSync(() => _coreSvc.PageService.FindBySiteAndUrlAsync(siteId, myURL));
if (cmsPage != null)
{
return true;
}
var cmsArticle = AsyncUtility.RunSync(() => _coreSvc.ArticleService.FindCategoryBySiteAndUrlAsync(siteId, myURL));
if (cmsArticle != null)
{
return true;
}
return false;
}
}
Problem: When MVC starts, it calls the parameterless constructor on CmsCoreRouting (because I told it to in url = new CmsCoreRouting()) but I am not sure how to both use AutoFac's DI so that I don't have to pass around my own instances of the service and repository and DbContext on this RegisterRoutes function.
Any help on this would be great. I would like to do this "right".
Just ask the resolver (AutoFac) to create it for you:
routes.MapRoute(
name: "CmsRoutes",
url: "{*permalink}",
defaults: new { controller = "CmsCorePage", action = "Index" },
constraints: new { url = DependencyResolver.Current.GetService<CmsCoreRouting>() }
);