通用的BehaviorExtensionElement是否可行?

时间:2011-01-20 22:48:50

标签: c# wcf generics configuration

我有一些我想要注册的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,并且已经过测试。

但是当我引用&lt; myBehavior2 /&gt;在配置文件的行为部分,我得到:

  

创建时出错   配置节处理程序   system.serviceModel /行为:   扩展元素'myBehavior2'不能   被添加到此元素。验证   扩展名已注册   扩展集合在   system.serviceModel /扩展/ behaviorExtensions。   参数名称:element

如果我创建一个非泛型的BehaviorExtensionElement后代,那么一切都有效,我可以这样做。但现在它让我烦恼。 ;)

2 个答案:

答案 0 :(得分:2)

不幸的是配置文件是不可能的,至少不是以可靠的方式。

原因是如果你有一个泛型类class A<T>和一个类参数class B,那么在你声明一个{{1}类型之前,框架不会创建一个类A<B>。通过使用它。格式为A`1 [[B,Assm]]的名称只是在运行时创建的名称 - 它表示通用“A”,它使用以下类型创建1个参数。它不是一个类型工厂的提示 - 这是你正在做的事情所需要的。所以你可能能够让它工作如果你很幸运并且A<B>恰好已被宣布,但我不会依赖它。

我认为,这是在框架的后续部分使用的数据协定序列化中修复的,但是配置是旧的。如果你看一下XAML,就可以使用类型为

的类型参数
A<B>

请注意,这是对类型工厂的显式指令 - 配置解析器具有的功能。

很遗憾,这会让你为每个扩展声明一个具体的类型 - 但这不是很多工作:

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

从好的方面来说,它使您的配置文件更具可读性。

public class MyBehaviorExtensionElement : 
         SimpleBehaviorExtensionElement<MyBehavior> {}

答案 1 :(得分:0)

是的,这是可能的。

我想抛出异常的原因是因为添加了行为元素WCF extensions without including the assembly version

在指定行为类型时,还会添加版本文化 PublicKeyToken 属性必须 。另请注意,必须在每个之后只有一个空格(逗号),并且属性必须按上述顺序出现。

因此,在您的示例中,以下应该有效:

 <behaviorExtensions>
    <add name="myBehavior2"
         type="WcfService1.SimpleBehaviorExtensionElement`1[[WcfService1.MyBehavior, WcfService1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], WcfService1" />
</behaviorExtensions>