标签:compile ict question use using which context cti .config
本文转自:http://www.cnblogs.com/miku/archive/2012/09/27/2706276.html
1. 映射路由
大型MVC项目为了扩展性,可维护性不能像一般项目在Global中RegisterRoutes的方法里面映射路由。
这里学习一下Nop是如何做的。
Global.cs . 通过IOC容器取得IRoutePublisher实例
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("favicon.ico");
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
//register custom routes (plugins, etc)
var routePublisher = EngineContext.Current.Resolve<IRoutePublisher>();
routePublisher.RegisterRoutes(routes);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional },
new[] { "Nop.Web.Controllers" }
);
}
IRoutePublisher.cs 只有一个方法
public interface IRoutePublisher
{
void RegisterRoutes(RouteCollection routeCollection);
}
实现类
public class RoutePublisher : IRoutePublisher
{
private readonly ITypeFinder _typeFinder;
public RoutePublisher(ITypeFinder typeFinder)
{
this._typeFinder = typeFinder;
}
public void RegisterRoutes(RouteCollection routes)
{
var routeProviderTypes = _typeFinder.FindClassesOfType<IRouteProvider>();
var routeProviders = new List<IRouteProvider>();
foreach (var providerType in routeProviderTypes)
{
var provider = Activator.CreateInstance(providerType) as IRouteProvider;
routeProviders.Add(provider);
}
routeProviders = routeProviders.OrderByDescending(rp => rp.Priority).ToList();
routeProviders.ForEach(rp => rp.RegisterRoutes(routes));
}
}
ITypeFinder之前已经介绍过。点击查看 ,搜索项目中所有的IRouteProvider实现。然后根据优先级排序,最后调用RegisterRoutes依次映射
竟然有这么多,大多都在Plugin程序集中为插件映射路由。随便打开一个。
public partial class RouteProvider : IRouteProvider
{
public void RegisterRoutes(RouteCollection routes)
{
routes.MapRoute("Plugin.Payments.AuthorizeNet.Configure",
"Plugins/PaymentAuthorizeNet/Configure",
new { controller = "PaymentAuthorizeNet", action = "Configure" },
new[] { "Nop.Plugin.Payments.AuthorizeNet.Controllers" }
);
routes.MapRoute("Plugin.Payments.AuthorizeNet.PaymentInfo",
"Plugins/PaymentAuthorizeNet/PaymentInfo",
new { controller = "PaymentAuthorizeNet", action = "PaymentInfo" },
new[] { "Nop.Plugin.Payments.AuthorizeNet.Controllers" }
);
}
public int Priority
{
get
{
return 0;
}
}
}
好处不用说了。模块化方便复用。
2.自定义Route
LocalizedRoute.cs
using System.Web;
using System.Web.Routing;
using Nop.Core.Data;
using Nop.Core.Domain.Localization;
using Nop.Core.Infrastructure;
namespace Nop.Web.Framework.Localization
{
/// <summary>
/// Provides properties and methods for defining a localized route, and for getting information about the localized route.
/// </summary>
public class LocalizedRoute : Route
{
#region Fields
private bool? _seoFriendlyUrlsForLanguagesEnabled;
#endregion
#region Constructors
/// <summary>
/// Initializes a new instance of the System.Web.Routing.Route class, using the specified URL pattern and handler class.
/// </summary>
/// <param name="url">The URL pattern for the route.</param>
/// <param name="routeHandler">The object that processes requests for the route.</param>
public LocalizedRoute(string url, IRouteHandler routeHandler)
: base(url, routeHandler)
{
}
/// <summary>
/// Initializes a new instance of the System.Web.Routing.Route class, using the specified URL pattern, handler class and default parameter values.
/// </summary>
/// <param name="url">The URL pattern for the route.</param>
/// <param name="defaults">The values to use if the URL does not contain all the parameters.</param>
/// <param name="routeHandler">The object that processes requests for the route.</param>
public LocalizedRoute(string url, RouteValueDictionary defaults, IRouteHandler routeHandler)
: base(url, defaults, routeHandler)
{
}
/// <summary>
/// Initializes a new instance of the System.Web.Routing.Route class, using the specified URL pattern, handler class, default parameter values and constraints.
/// </summary>
/// <param name="url">The URL pattern for the route.</param>
/// <param name="defaults">The values to use if the URL does not contain all the parameters.</param>
/// <param name="constraints">A regular expression that specifies valid values for a URL parameter.</param>
/// <param name="routeHandler">The object that processes requests for the route.</param>
public LocalizedRoute(string url, RouteValueDictionary defaults, RouteValueDictionary constraints, IRouteHandler routeHandler)
: base(url, defaults, constraints, routeHandler)
{
}
/// <summary>
/// Initializes a new instance of the System.Web.Routing.Route class, using the specified URL pattern, handler class, default parameter values,
/// constraints,and custom values.
/// </summary>
/// <param name="url">The URL pattern for the route.</param>
/// <param name="defaults">The values to use if the URL does not contain all the parameters.</param>
/// <param name="constraints">A regular expression that specifies valid values for a URL parameter.</param>
/// <param name="dataTokens">Custom values that are passed to the route handler, but which are not used to determine whether the route matches a specific URL pattern. The route handler might need these values to process the request.</param>
/// <param name="routeHandler">The object that processes requests for the route.</param>
public LocalizedRoute(string url, RouteValueDictionary defaults, RouteValueDictionary constraints, RouteValueDictionary dataTokens, IRouteHandler routeHandler)
: base(url, defaults, constraints, dataTokens, routeHandler)
{
}
#endregion
#region Methods
/// <summary>
/// Returns information about the requested route.
/// </summary>
/// <param name="httpContext">An object that encapsulates information about the HTTP request.</param>
/// <returns>
/// An object that contains the values from the route definition.
/// </returns>
public override RouteData GetRouteData(HttpContextBase httpContext)
{
if (DataSettingsHelper.DatabaseIsInstalled() && this.SeoFriendlyUrlsForLanguagesEnabled)
{
string virtualPath = httpContext.Request.AppRelativeCurrentExecutionFilePath;
string applicationPath = httpContext.Request.ApplicationPath;
if (virtualPath.IsLocalizedUrl(applicationPath, false))
{
//In ASP.NET Development Server, an URL like "http://localhost/Blog.aspx/Categories/BabyFrog" will return
//"~/Blog.aspx/Categories/BabyFrog" as AppRelativeCurrentExecutionFilePath.
//However, in II6, the AppRelativeCurrentExecutionFilePath is "~/Blog.aspx"
//It seems that IIS6 think we‘re process Blog.aspx page.
//So, I‘ll use RawUrl to re-create an AppRelativeCurrentExecutionFilePath like ASP.NET Development Server.
//Question: should we do path rewriting right here?
string rawUrl = httpContext.Request.RawUrl;
var newVirtualPath = rawUrl.RemoveLocalizedPathFromRawUrl(applicationPath);
if (string.IsNullOrEmpty(newVirtualPath))
newVirtualPath = "/";
newVirtualPath = newVirtualPath.RemoveApplicationPathFromRawUrl(applicationPath);
newVirtualPath = "~" + newVirtualPath;
httpContext.RewritePath(newVirtualPath, true);
}
}
RouteData data = base.GetRouteData(httpContext);
return data;
}
/// <summary>
/// Returns information about the URL that is associated with the route.
/// </summary>
/// <param name="requestContext">An object that encapsulates information about the requested route.</param>
/// <param name="values">An object that contains the parameters for a route.</param>
/// <returns>
/// An object that contains information about the URL that is associated with the route.
/// </returns>
public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
{
VirtualPathData data = base.GetVirtualPath(requestContext, values);
if (DataSettingsHelper.DatabaseIsInstalled() && this.SeoFriendlyUrlsForLanguagesEnabled)
{
if (data != null)
{
string rawUrl = requestContext.HttpContext.Request.RawUrl;
string applicationPath = requestContext.HttpContext.Request.ApplicationPath;
if (rawUrl.IsLocalizedUrl(applicationPath, true))
{
data.VirtualPath = string.Concat(rawUrl.GetLanguageSeoCodeFromUrl(applicationPath, true), "/",
data.VirtualPath);
}
}
}
return data;
}
public virtual void ClearSeoFriendlyUrlsCachedValue()
{
_seoFriendlyUrlsForLanguagesEnabled = null