加强类/方法的属性修饰
接下来是我最近关于大型复杂对象作为Web服务结果的问题。我一直在思考如何确保将来的所有子类都可序列化为XML。
现在,很明显,我可以实现IXmlSerializable接口,然后再吸引它的读取器/写入器,但是我想避免这种情况,因为这意味着我需要在需要的时候实例化读取器/写入器,并且99.99%的时间我将使用一个字符串,所以我可以自己写一个。
但是,要序列化为XML,我只是用Xml装饰类及其成员???属性(XmlRoot,XmlElement等),然后将其传递给XmlSerializer和StringWriter以获取字符串。一切都很好。我打算将方法用于将字符串返回到通用实用程序方法中,所以我不必担心类型等。
我关心的是这样的:如果我不使用必需的属性装饰类,则直到运行时才会引发错误。
有什么方法可以强制执行属性修饰?可以用FxCop完成吗? (我还没有使用过FxCop)
更新:
对不起,让我们与众不同的事情拖延了,还有很多事要做!
绝对喜欢在测试用例中使用反射而不是求助于FxCop的想法(喜欢将所有内容放在一起)。Fredrik Kalseth的回答很棒,感谢我们提供了代码,因为这可能会使我费劲自己弄清楚怎么做!
向其他人+1提出类似的建议:)
解决方案
回答
我要编写一个单元/集成测试,以验证与某些给定条件匹配的任何类(即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); } } } }
回答
我们可以编写单元测试来检查这种事情,它基本上使用反射。
鉴于事实是可能的,我想也可以编写FxCop规则,但是我从未做过这样的事情。
回答
我们可以编写FxCop规则,甚至可以通过在基类的构造函数中调用GetType()并检查返回的类型来检查属性。
回答
一个好的FXCop规则(以及我现在发现我需要的一个规则)是检查要添加到ASP.NET会话中的所有对象都具有Serializable属性。我正在尝试从InProc会话状态转移到SQL Server。第一次请求页面时,我的网站在我眼前一亮,因为无法序列化的对象存储在Session中。然后是搜寻所有源代码以寻找在Session中设置对象的每个实例的任务... FXCop将是一个不错的解决方案。有事可做...
回答
我们还可以使用此概念/后处理器来加强属性之间的关系,并在编译时使用类似的登录名来加强类和属性之间的关系:
http://www.st.informatik.tu-darmstadt.de/database/publications/data/cepa-mezini-gpce04.pdf?id=92