开发者

Add #if/#endif directives to DataContract attribute on CodeTypeDefinition of generated class

I'm working with an XSD -> C# class parser which generates classes for our data model, which is to be shared between a WPF client and a Silverlight web-based portion.

We are trying to augment the generated classes with [DataContract] attributes that should only be used when the SILVERLIGHT symbol is not defined, i.e.:

#if !SILVERLIGHT
[DataContract]
#endif
public clas开发者_如何转开发s Class1 { /* ... */ }

How can I add this #if / #endif block to the CodeTypeDefinition of the Class1, or to the CodeAttributeDeclaration of DataContract?


Not sure how to get #if's emitted but you could instead generate two different versions of the class (one with the DataContract attribute, one without) and use a ConditionalAttribute (http://msdn.microsoft.com/en-us/library/system.diagnostics.conditionalattribute.aspx) on them so the correct one is used for each environment

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


What I've actually decided to do is add the #if / #endif tags through a Python script, after the code file is generated. Robert's reply is functionally valid, but I just didn't feel right using two separate classes when one should be just fine.

Although it introduces another language into the data model generation, this seems like the cleanest way to get exactly what I want. The script we are using is below. It only needs to check for NonSerializable attributes (specifically, on PropertyChanged events) now because of a new way we structured the data contract.

#!/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()


I wouldn't suggest adding the [DataContract] attribute on a generated class, since it will be overwritten when the class will be regenerated. If I were you, I would consider mapping your data model into DTOs (data transfer object) that will have the [DataContract] attribute using the method Robert Levy explained.

You can use AutoMapper to help you map your model to your DTOs.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜