【问题标题】:How to get started with taking a dynamic model class and filling it with data如何开始使用动态模型类并用数据填充它
【发布时间】:2012-10-03 21:49:09
【问题描述】:

我有一个小型路由引擎。它匹配模式并填充路由参数字典。因此/blog/{action}/{id} 将匹配/blog/view/123 并将123 作为id 的键的值放在字典中等等。

有趣的部分来了。我想改变这个系统,改为使用模型类型的架构,所以我可以有类似的东西

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 都会做类似的事情。是否有任何教程或类似的东西可以开始这样的事情?

【问题讨论】:

    标签: .net dynamic reflection


    【解决方案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
    }
    

    【讨论】:

    • 这实际上与我的意图相反,尽管这是一个很好的开始(我将完全需要路由以从“路由模型”生成 URL)
    猜你喜欢
    • 2014-03-31
    • 1970-01-01
    • 2014-12-13
    • 2019-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-17
    相关资源
    最近更新 更多