0

私は小さなルーティングエンジンを持っています。パターンを照合し、ルート パラメータのディクショナリに入力します。そのため、辞書などのキーに/blog/{action}/{id}一致して値として/blog/view/123配置されます。123id

ここが楽しい部分です。このシステムを代わりにモデル型アーキテクチャを使用するように変更したいので、代わりに次のようなものを使用できます

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

もちろん、他にもルートの「モデル」などは/comments/{action}/{entryid}/{id}あるので、これはやる必要があると思います

私の最終的な目標は、基本的にAddRoute("pattern", new BlogRoute())似たようなものを持ち、ルーターが動的にデータを BlogRoute インスタンスに入力することです

どうすればこれを始められますか? 私はリフレクションをほとんど使用したことがありません (奇妙なことに、IL には非常に精通しています)。これは少し気が遠くなるような気がします。これは、他の複数のライブラリでも行われます。基本的に、すべての ORM はこれと同様のことを行います。このようなことを始めるためのチュートリアルなどはありますか?

4

1 に答える 1

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
}
于 2012-10-15T03:42:03.777 に答える