将#if / #endif指令添加到生成的类的CodeTypeDefinition上的DataContract属性

时间:2011-08-31 16:35:38

标签: c# datacontract codedom

我正在使用XSD - > C#类解析器,它为我们的数据模型生成类,这些类将在WPF客户端和基于Weblight的Silverlight部分之间共享。

我们正在尝试使用[DataContract]属性来扩充生成的类,这些属性只应在未定义SILVERLIGHT符号时使用,即:

#if !SILVERLIGHT
[DataContract]
#endif
public class Class1 { /* ... */ }

如何将此#if / #endif块添加到 Class1 CodeTypeDefinition DataContract CodeAttributeDeclaration

3 个答案:

答案 0 :(得分:1)

不确定如何发送#if,但你可以生成两个不同版本的类(一个具有DataContract属性,一个没有)并使用ConditionalAttribute(http://msdn.microsoft.com/en-us /library/system.diagnostics.conditionalattribute.aspx),因此每个环境都使用正确的

  CodeAttributeDeclaration declaration1 =
    new CodeAttributeDeclaration(
      "System.Diagnostics.ConditionalAttribute",
      new CodeAttributeArgument(
        new CodePrimitiveExpression("SILVERLIGHT")));

答案 1 :(得分:0)

我不建议在生成的类上添加[DataContract]属性,因为在重新生成类时它将被覆盖。如果我是你,我会考虑使用解释的方法Robert Levy将您的数据模型映射到具有[DataContract]属性的DTO(数据传输对象)。

您可以使用AutoMapper帮助您将模型映射到DTO。

答案 2 :(得分:0)

我实际上决定在生成代码文件后通过Python脚本添加#if / #endif标记。罗伯特的回复在功能上是有效的,但是当一个应该时,我只是觉得使用两个单独的类是不对的。

虽然它在数据模型生成中引入了另一种语言,但这似乎是获得我想要的最简洁的方法。我们使用的脚本如下。它现在只需要检查NonSerializable属性(特别是在PropertyChanged事件上),因为我们构建了数据协定的新方法。

#!/usr/bin/env python

import sys
from optparse import OptionParser
import shutil

# Use OptionParser to parse script arguments.
parser = OptionParser()

# Filename argument.
parser.add_option("-f", "--file", action="store", type="string", dest="filename", help="C# class file to parse", metavar="FILE.cs")

# Parse the arguments to the script.
(options, args) = parser.parse_args()

# The two files to be used: the original and a backup copy.
filename = options.filename

# Read the contents of the file.
f = open( filename, 'r' )
csFile = f.read()
f.close()

# Add #if tags to the NonSerialized attributes.
csFile = csFile.replace('        [field: NonSerialized()]',
                    '        #if !SILVERLIGHT\r\n        [field: NonSerialized()]\r\n        #endif')

# Rewrite the file contents.
f = open( filename, 'r' )
f.write(csFile)
f.close()