只需浏览具有 RouteParam 属性的属性。如果获取传递给属性的构造函数的值和传递给AddRoute的某个路由信息对象上的属性本身的值,就可以获得所有的路由信息。
我不确定反射是否明显缓慢,但在性能关键的情况下我会远离它。您可以将这种使用反射的方法替换为您有一个 RouteData 类的方法,其中只需包含一个字典。但是你失去了美丽的声明性做事方式。你选。
/// <summary>
/// This is your custom attribute type that you will use to annotate properties as route information.
/// </summary>
class RouteParamAttribute : Attribute
{
public string RouteKey;
public RouteParamAttribute(string routeKey)
{
RouteKey = routeKey;
}
}
/// <summary>
/// From which all other routes inherit. This is optional and is used to avoid passing any kind of object to AddRoute.
/// </summary>
class Route
{
}
/// <summary>
/// This is an actual route class with properties annotated with RouteParam because they are route information pieces.
/// </summary>
class BlogRoute : Route
{
[RouteParam("action")]
public string Action { get; set; }
[RouteParam("id")]
public string ID { get; set; }
}
/// <summary>
/// This is all the reflection happen to add routes to your route system.
/// </summary>
/// <param name="routeInformation"></param>
void AddRoute(Route routeInformation)
{
//Get the type of the routeInformation object that is passed. This will be used
//to get the route properties and then the attributes with which they are annotated.
Type specificRouteType = routeInformation.GetType(); //not necessarily Route, could be BlogRoute.
//The kind of attribute that a route property should have.
Type attribType = typeof(RouteParamAttribute);
//get the list of props marked with RouteParam (using attribType).
var routeProperties = specificRouteType.GetProperties().Where(x => x.GetCustomAttributes(attribType, false).Count() >= 1);
//this where we'll store the route data.
Dictionary<string, string> routeData = new Dictionary<string, string>();
//Add the data in each route property found to the dictionary
foreach (PropertyInfo routeProperty in routeProperties)
{
//Get the attribute as an object (because in it we have the "action" or "id" or etc route key).
var rpa = routeProperty.GetCustomAttributes(attribType, false).First() as RouteParamAttribute;
//The value of the property, this is the value for the route key. For example if a property
//has an attribute RouteParam("action") we would expect the value to be "blog" or "comments"
var value = routeProperty.GetValue(routeInformation, null);
//convert the value to string (or object depending on your needs, be careful
//that it must match the dictionary though)
string stringValue = "";
if (value != null)
stringValue = value.ToString();
else ; //throw an exception?
routeData.Add(rpa.RouteKey, stringValue);
}
//now you have a dictionary of route keys (action, id, etc) and their values
//manipulate and add them to the route system
}