Добавьте директивы # if / # endif в атрибут DataContract для CodeTypeDefinition сгенерированного класса - PullRequest
0 голосов
/ 31 августа 2011

Я работаю с синтаксическим анализатором классов XSD -> C #, который генерирует классы для нашей модели данных, которые должны быть разделены между клиентом WPF и частью Silverlight на веб-сайте.

Мы пытаемся дополнить сгенерированные классы атрибутами [DataContract], которые следует использовать только в том случае, если символ SILVERLIGHT не определен, т. Е .:

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

Как добавить этот блок #if / #endif к CodeTypeDefinition Class1 или к CodeAttributeDeclaration из DataContract ?

Ответы [ 3 ]

1 голос
/ 31 августа 2011

Не уверен, как получить #, если испущено, но вы могли бы вместо этого сгенерировать две разные версии класса (одну с атрибутом 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")));
0 голосов
/ 15 сентября 2011

На самом деле я решил добавить теги #if / #endif через скрипт Python после генерации файла кода. Ответ Роберта является функционально верным, но я просто не чувствовал себя хорошо, когда использовал два отдельных класса, когда один должен быть в порядке.

Хотя это вводит другой язык в генерацию модели данных, это кажется самым чистым способом получить именно то, что я хочу. Сценарий, который мы используем, ниже. Теперь нужно только проверить атрибуты 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()
0 голосов
/ 31 августа 2011

Я бы не советовал добавлять атрибут [DataContract] в сгенерированный класс, так как он будет перезаписан при повторном создании класса. На вашем месте я бы рассмотрел отображение вашей модели данных в DTO (объект передачи данных), который будет иметь атрибут [DataContract] с использованием метода Robert Levy .

Вы можете использовать AutoMapper , чтобы помочь вам сопоставить вашу модель с вашими DTO.

...