强制类/方法属性装饰的实施

18

在我最近提出的问题(Web服务结果中的大型复杂对象)后,我一直在思考如何确保所有未来的子类都可以序列化为XML。

显然,我可以实现IXmlSerializable接口,然后将一个读取器/写入器扔给它,但是我想避免这样做,因为那就意味着每当我想这样做时都需要实例化一个读取器/写入器,而99.99%的时间我将使用字符串,所以我可能会自己编写一个。

然而,要将其序列化为XML,我只需使用Xml???属性(例如XmlRootXmlElement等)装饰类及其成员,然后将其传递给XmlSerializerStringWriter以获取字符串。这很好。我打算将返回字符串的方法放入通用的实用方法中,这样我就不必担心类型等问题。

我担心的是:如果我没有对类进行所需的属性装饰,那么在运行时才会抛出错误。

有没有办法强制执行属性装饰?FxCop可以做到吗?(我还没有使用FxCop)

更新:

抱歉让你们久等了,要做的事情太多了!

绝对喜欢使用反射在测试用例中来实现,而不是诉诸于FxCop(喜欢将所有内容放在一起)...Fredrik Kalseth的答案非常好,感谢包含代码,因为如果要自己找出如何做这件事可能需要花费一些时间!

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

5个回答

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
你可以编写单元测试来检查这种情况 - 它基本上使用反射。
鉴于这是可能的,我想编写FxCop规则也是可能的,但我从未尝试过这样做。

1

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


0
一个好的FXCop规则(我现在正在需要的一种)是检查所有被添加到ASP.NET Session中的对象是否具有Serializable属性。我正在尝试从InProc会话状态转移到SQL Server。第一次请求页面时,我的站点崩溃了,因为非可序列化对象被存储在会话中。然后就是在所有源代码中寻找每个设置在Session中的对象的实例的任务...FXCop将是一个不错的解决方案。有些东西需要改进...

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接