实施类/方法的属性装饰

时间:2008-08-21 07:49:56

标签: c# xml serialization coding-style .net-attributes

继我最近关于Large, Complex Objects as a Web Service Result的问题之后。我一直在考虑如何确保所有未来的子类都可以序列化为XML。

现在,显然我可以实现IXmlSerializable接口,然后读取它的读者/写入器,但我想避免这种情况,因为它意味着我需要在我想要的时候实例化读写器,99.99%的时间我将使用字符串,所以我可以自己编写。

但是,为了序列化为XML,我只是使用 Xml ??? 属性( XmlRoot XmlElement )来修饰类及其成员。 >等)然后将其传递给 XmlSerializer StringWriter 以获取字符串。这一切都很好。我打算把方法返回到一个通用的实用工具方法,所以我不需要担心类型等。

关注我的是:如果我没有使用必需的属性装饰类,则在运行时才会抛出错误。

有没有办法强制执行属性修饰?可以用FxCop完成吗?(我还没有用过FxCop)

更新

对于延迟让这些人关闭,很多事情要做!

绝对喜欢在测试用例中使用反射来实现它而不是诉诸于FxCop(想要将所有内容保持在一起)。Fredrik Kalseth's answer非常棒,感谢包含可能会采用的代码我自己想了解如何自己做这件事!

+1给其他人提出类似的建议:)

5 个答案:

答案 0 :(得分:19)

我编写了一个单元/集成测试,用于验证符合某些给定条件的任何类(即子类化X)是否已正确修饰。如果将构建设置为使用测试运行,则可以在此测试失败时使构建失败。

更新:你说,“看起来我只需要卷起袖子,确保单元测试得到集体维护” - 你没必要。只需编写一个通用测试类,它使用反射来查找需要断言的所有类。像这样:

[TestClass]
public class When_type_inherits_MyObject
{
    private readonly List<Type> _types = new List<Type>();

    public When_type_inherits_MyObject()
    {
        // lets find all types that inherit from MyObject, directly or indirectly
        foreach(Type type in typeof(MyObject).Assembly.GetTypes())
        {
            if(type.IsClass && typeof(MyObject).IsAssignableFrom(type))
            {
                _types.Add(type);
            }
        }
    }

    [TestMethod]
    public void Properties_have_XmlElement_attribute
    {
        foreach(Type type in _types)
        {
            foreach(PropertyInfo property in type.GetProperties())
            {
                object[] attribs = property.GetCustomAttributes(typeof(XmlElementAttribute), false);
                Assert.IsTrue(attribs.Count > 0, "Missing XmlElementAttribute on property " + property.Name + " in type " + type.FullName);
            }
        }
    }
}

答案 1 :(得分:1)

您可以编写单元测试来检查这种事情 - 它基本上使用反射。

鉴于这是可能的,我想我也可以写一个FxCop规则,但我从来没有做过这样的事情。

答案 2 :(得分:1)

您可以编写FxCop规则,甚至可以通过在基类的构造函数中调用GetType()并反映返回的类型来检查属性。

答案 3 :(得分:0)

一个好的FXCop规则(我现在发现我需要的规则)是检查所有添加到ASP.NET Session的对象是否具有Seri​​alizable属性。我正在尝试从InProc会话状态转移到SQL Server。我第一次请求页面,我的网站爆炸了我,因为不可序列化的对象存储在Session中。接下来的任务是搜索所有源代码,寻找在Session中设置对象的每个实例... FXCop将是一个很好的解决方案。要做的事......

答案 4 :(得分:0)

您还可以使用此概念/后处理器来强制执行属性之间的关系,并使用类似的登录在编译时强制实现类和属性之间的关系:

http://www.st.informatik.tu-darmstadt.de/database/publications/data/cepa-mezini-gpce04.pdf?id=92