加强类/方法的属性修饰

时间:2020-03-05 18:41:25  来源:igfitidea点击:

接下来是我最近关于大型复杂对象作为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会话中的所有对象都具有Seri​​alizable属性。我正在尝试从InProc会话状态转移到SQL Server。第一次请求页面时,我的网站在我眼前一亮,因为无法序列化的对象存储在Session中。然后是搜寻所有源代码以寻找在Session中设置对象的每个实例的任务... FXCop将是一个不错的解决方案。有事可做...

回答

我们还可以使用此概念/后处理器来加强属性之间的关系,并在编译时使用类似的登录名来加强类和属性之间的关系:

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