以.NET Web程序注册全局路由为例,先看以下的代码
1、路由Route类,包含一个IHttpHandler,一个处理请求程序的属性,在构造函数中需要去传递一个IHttpHandler的一个对象
public class Route
{
public Route(string url, object defaults, IHttpHandler handler)
{
this.Url = url;
this.RouteHandler = handler;
Defaults = new Dictionary<string, object>();
var defaultsProps = defaults.GetType().GetProperties();
foreach (var item in defaultsProps)
{
Defaults.Add(item.Name, item.GetValue(defaults));
}
}
public string Url { get; set; }
/// <summary>
/// 当前请求处理程序
/// </summary>
public IHttpHandler RouteHandler { get; set; }
public IDictionary<string, object> Defaults { get; set; }
}
2、程序全局入口,注册全局的路由表
protected void Application_Start(object sender, EventArgs e)
{
RouteTable.Routes.MapRoute(
"{controller}/{action}",
new { Controller = "Product", Action = "Execute" });
}
3、通过一个扩展方法MapRoute去注册全局路由表,在这个扩展方法中去注册IHttpHandler时,new一个MvcHandler(继承IHttpHandler的具体对象)作为参数传递过去
public static class RouteExtend
{
public static void MapRoute(this IList<Route> source, string url, object defaults)
{
MapRoute(source, url, default, new MvcHandler());
}
public static void MapRoute(this IList<Route> source, string url, object defaults, IHttpHandler handler)
{
source.Add(new Route(
url,
defaults,
handler));
}
}
4、当解析完路由,分配好处理的路由对象时可以通过route.RouteHandler()来得到对象,并执行其他的一系列操作。
route.RouteHandler()
当这样去coding代码的时候,会存在几个问题:
①:在构造路由时,会直接去new一个对象,而且不管这个对象是否要被调用,都会去new
②:当地址访问时,会造成对象的共享问题,一直存在静态路由集合RouteTable.Routes属性中,会造成无法释放,占用内存的情况
所以,可以修改程序,利用委托的方式来进行代码的优化
1、首先我们来修改Route类,将原来的静态属性RouteHandler,改为委托的Func<IHttpHandler>的形式
public class Route
{
public Route(string url, object defaults, Func<IHttpHandler> getHandler)
{
this.Url = url;
this.GetRouteHandler = getHandler;
Defaults = new Dictionary<string, object>();
var defaultsProps = defaults.GetType().GetProperties();
foreach (var item in defaultsProps)
{
Defaults.Add(item.Name, item.GetValue(defaults));
}
}
public string Url { get; set; }
/// <summary>
/// 当前请求处理程序
/// </summary>
public Func<IHttpHandler> GetRouteHandler { get; set; }
public IDictionary<string, object> Defaults { get; set; }
}
2、在通过扩展方法注册全局路由表的时候,传递一个匿名的委托,委托里面来进行new操作
public static class RouteExtend
{
public static void MapRoute(this IList<Route> source, string url, object defaults)
{
MapRoute(source, url, default, () => { return new MvcHandler(); });
}
public static void MapRoute(this IList<Route> source, string url, object defaults, Func<IHttpHandler> getHandler)
{
source.Add(new Route(
url,
defaults,
getHandler));
}
}
3、这样在外部调用的时候,就可以通过执行委托的形式来获得对象,然后在进行其他的操作
var handler = route.GetRouteHandler();
这样做的好处:
①:当我们在构造的时候,并不传入具体的对象,而是传入一个允许创建对象的操作,只有当我们真正调用的时候,才会去创建对象
②:相比于之前的静态属性而言,静态属性是会被存储在内存中的,而通过委托,创建出来方法的返回值,是不会存储的,这样对内存而言是一种优化。