Общие характеристики WCF. Почему DataContract и CollectionDataContract допускают форматированное именование, но не DataMember, OperationContract или ServiceContract? - PullRequest
2 голосов
/ 28 июня 2011

В основном, как гласит заголовок:

[DataContract(Name = "{0}Item")] //This will format properly
public class GenericItem<T>
{
    [DataMember(Name = "The{0}")] //This will NOT format properly
    public T TheItem { get; set; }
}

[CollectionDataContract(Name = "{0}Items")] //This will format properly
public SpecialCollection<T> : Collection<T> { }

[ServiceContract(Name = "{0}Service")] //This will NOT format properly
public interface IGenericService<T>
{
    [OperationContract(Name = "Get{0}")] //This will NOT format properly
    GenericItem<T> Get<T>();
}

Итак, у вас есть ... что работает и не работает ... но вопрос ... почему? Очевидно, что .NET способен создавать конкретный тип и форматировать имя при использовании DataContract и CollectionDataContract и указание типа (то есть GenericItem<Foo> или SpecialCollection<Foo>. Так почему бы не DataMember также иметь возможность форматирования?

ServiceContract/OperationContract Я могу в некотором роде понять, как это было описано выше (сортировка), но я не понимаю, когда вы придаете ему конкретный тип, операции все равно не будут работать должным образом:

[ServiceContract(Name = "FooService")]
public interface FooService : IGenericService<Foo> { }

public interface IGenericService<T>
{
    [OperationContract(Name = "Get{0}")] //This will NOT format properly
    T Get<T>();
}

Опять же, почему ? Очевидно, что здесь я объявляю конкретный тип Foo, что означает, что IGenericService является IGenericService , поэтому не следует ли форматировать имя OperationContract, поскольку оно ЗНАЕТ тип?


Обновление:

Я только что вспомнил, почему я расстроился из-за того, что не смог использовать универсально отформатированный ServiceContract ... когда у меня есть реализация службы, я даю ей конкретный тип ...

//See! I gave it a concrete type to go by!
[ServiceBehavior(...)]
public class MyService : IGenericService<Foo> { ... }

Я создал для этого Microsoft Connect запрос. Пожалуйста, подпишите его, если вы хотите эту функцию для других атрибутов. http://visualstudio.uservoice.com/forums/121579-visual-studio/suggestions/2327048-enable-generics-for-datamemberattribute-serviceco

Ответы [ 2 ]

1 голос
/ 29 июня 2011

Это похоже на выбор реализации MS.В System.Runtime.Serialization.DataContract он создает имя, выполняя:

private static XmlQualifiedName GetDCTypeStableName(Type type, DataContractAttribute dataContractAttribute)
{
  string localName;
  if (dataContractAttribute.IsNameSetExplicit)
  {
    string str = dataContractAttribute.Name;
    if (str == null || str.Length == 0)
    {
       ...
    }
    else
    {
      if (type.IsGenericType && !type.IsGenericTypeDefinition)
        str = DataContract.ExpandGenericParameters(str, type);
      localName = DataContract.EncodeLocalName(str);
    }
  }

Таким образом, он явно создает общее имя.В случае с ServiceContract, он обрабатывается в System.ServiceModel.Description.TypeLoader и System.ServiceModel.Description.NamingHelper и ничего не делает с универсальными типами (наконец-то не то, что я вижу).

Так что я думаю, так как ониконтракты проистекают из разных сборок и пространств имен, они могли быть реализованы разными командами с самого начала.

0 голосов
/ 29 июня 2011

Читать это: http://msdn.microsoft.com/en-us/library/ms731045.aspx#Y1254

По сути, кажется, что система имен изначально была разработана без возможности форматировать имена, но в итоге система имен DataContract раздражала достаточно людей (из-за хеша), что они добавили возможность форматировать их имена.

EDIT:

"Однако могут быть причины для изменения этого имени по умолчанию. Одна из причин - позволить существующему типу обрабатывать данные, которые должны соответствовать существующему контракту данных. Например, существует тип с именем Person, но контракт данных, В XML-схеме требуется, чтобы имя было Customer. Контракт может быть выполнен путем установки значения свойства Customer.

Вторая причина - разрешить генерацию имен, которые недопустимы в качестве имен типов. Например, если контракт данных требует имя, которое недопустимо в качестве имени типа, задайте для свойства значение этого запрещенного имени. Например, строка «$ value» запрещена в качестве имени типа, но допускается в качестве значения свойства Name. "

Источник: http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datacontractattribute.name.aspx

Мое предположение, опять же, заключается в том, что не требуется необходимости для изменения имени других по умолчанию (включая OperationContract, ServiceContract и т. Д.).

...