2012-10-13 4 views
0

작은 라우팅 엔진이 있습니다. 패턴과 일치하고 경로 매개 변수 사전을 채 웁니다. 따라서 /blog/{action}/{id}/blog/view/123과 일치하고 사전에 id 키의 값으로 123을 입력합니다.동적 모델 클래스를 가져 와서 데이터로 채우기 시작하는 방법

재미있는 부분이 있습니다. 내가 대신 모델 형 아키텍처를 사용하는이 시스템을 변경하려면, 그래서 내가 대신 등이 다른 경로 "모델"뿐만 아니라 같은 /comments/{action}/{entryid}/{id} 등이며, 물론

class BlogRoute 
{ 
    [RouteParam("action")] 
    public string Action{get;set;} 
    [RouteParam("id")] 
    public string ID{get;set;} 
} 

같은 것을, 그래서 수 있습니다 내가

내 최종 목표는 내가이 일을 시작하는 것이 어떻게 BlogRoute 인스턴스

AddRoute("pattern", new BlogRoute()) 또는 유사한 내 라우터가 동적으로 데이터를 입력 같은 것을 가지고 기본적으로 반사와 생각이 작업을 수행 할 필요가? 나는 거의 전혀 반사를 사용하지 않았다. (비록 이상하게도 일리노이에 익숙하다.) 약간 어려운 것처럼 보이기 때문에 약간의 성능이 중요하기 때문에 다소 차선책으로 작업하는 것을 두려워한다. 이것은 여러 다른 라이브러리에서도 수행됩니다. 기본적으로 모든 ORM은 이와 비슷한 작업을 수행합니다. 이와 같은 것을 시작하기위한 자습서가 있습니까?

+0

내 대답이 도움이됩니까? – Mzn

답변

1

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 
} 
+0

실제로 이것은 다른 방향으로가는 좋은 출발점이긴하지만 실제로 내가 의도 한 것과는 반대 방향입니다 ("경로 모델"에서 URL을 생성하기 위해 라우팅에 정확히 필요합니다). – Earlz

관련 문제