Возможен ли универсальный элемент BehaviorExtensionElement? - PullRequest
6 голосов
/ 21 января 2011

У меня есть некоторые сервисные поведения для сервисов WCF, которые я просто хочу зарегистрировать;Там нет конфигурации.Я решил, что могу пропустить создание потомка BehaviorExtensionElement каждый раз, используя обобщенные значения:

public class SimpleBehaviorExtensionElement<TBehavior> : BehaviorExtensionElement
    where TBehavior: new()
{
    protected override object CreateBehavior()
    {
        return new TBehavior();
    }

    public override Type BehaviorType
    {
        get { return typeof(TBehavior); }
    }
}

А в Web.config:

<behaviorExtensions>
  <add name="myBehavior2"
    type="WcfService1.SimpleBehaviorExtensionElement`1[[WcfService1.MyBehavior,
      WcfService1]], WcfService1"/>
</behaviorExtensions>

WcfService1.MyBehavior существует, реализует IServiceBehavior и былиспытания.

Но когда я ссылаюсьв разделе поведения файла конфигурации я получаю:

Произошла ошибка при создании обработчика раздела конфигурации для system.serviceModel / поведения: Элемент расширения 'myBehavior2' не может быть добавлен к этому элементу.Убедитесь, что расширение зарегистрировано в коллекции расширений в system.serviceModel / extensions / поведениеExtensions.Имя параметра: element

Все работает, если я создаю неуниверсальный потомок BehaviorExtensionElement, что я могу сделать.Но теперь это меня беспокоит.;)

Ответы [ 2 ]

2 голосов
/ 12 февраля 2011

К сожалению, это невозможно с конфигурационными файлами, по крайней мере, не надежным способом.

Причина в том, что если у вас есть универсальный класс class A<T> и параметр класса class B, то среда не создаст класс A<B>, пока вы не объявите тип A<B>, используя его.Имя в формате A`1 [[B, Assm]] - это просто имя, которое создается во время выполнения - это означает универсальный «A», который принимает 1 параметр, созданный со следующими типами.Это не подсказка фабрике типов - это то, что вам нужно для того, что вы делаете.Таким образом, вы могли бы иметь возможность заставить это работать , если вам повезет и A<B> окажется объявленным, но я бы не стал полагаться на это.

Это, я считаю, исправлено в сериализации контракта данных, которая используется более поздними частями платформы, но конфигурация устарела.Если вы посмотрите на XAML, то сможете использовать аргументы типа с типом:

<scg3:Dictionary x:TypeArguments="x:String, x:Object">

Обратите внимание, что это явная инструкция для фабрики типов - то, что синтаксический анализатор конфигурации делает не have.

Так что, к сожалению, это оставляет вас за счет объявления конкретного типа для каждого расширения - но это не так много работы:

public class MyBehaviorExtensionElement : 
         SimpleBehaviorExtensionElement<MyBehavior> {}

И с положительной стороны этоделает ваш конфигурационный файл более читабельным.

<behaviorExtensions>
  <add name="myBehavior" 
    type="BehaviorTest.MyBehaviorExtensionElement, ServiceLibrary"/>      
</behaviorExtensions>
0 голосов
/ 05 февраля 2011

Да, это возможно.

Я полагаю, причина, по которой генерируется исключение, заключается в способе добавления элементов поведения Расширения WCF без учета версии сборки .

При указании типа поведения также можно добавить Версия , Культура и PublicKeyToken атрибуты ДОЛЖНЫ .Также обратите внимание, что ДОЛЖЕН быть ровно через один пробел после каждого (запятая), а атрибуты ДОЛЖНЫ отображаются в указанном выше порядке.

Итак, в вашем примере,должно работать следующее:

 <behaviorExtensions>
    <add name="myBehavior2"
         type="WcfService1.SimpleBehaviorExtensionElement`1[[WcfService1.MyBehavior, WcfService1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], WcfService1" />
</behaviorExtensions>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...