通用的BehaviorExtensionElement是否可行?

Tru*_*ill 6 c# generics configuration wcf

我有一些我想要注册的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); }
    }
}
Run Code Online (Sandbox Code Playgroud)

在Web.config中:

<behaviorExtensions>
  <add name="myBehavior2"
    type="WcfService1.SimpleBehaviorExtensionElement`1[[WcfService1.MyBehavior,
      WcfService1]], WcfService1"/>
</behaviorExtensions>
Run Code Online (Sandbox Code Playgroud)

WcfService1.MyBehavior存在,实现了IServiceBehavior,并且已经过测试.

但是当我在配置文件的行为部分中引用<myBehavior2 />时,我得到:

为system.serviceModel/behavior创建配置节处理程序时发生错误:无法将扩展元素"myBehavior2"添加到此元素.验证扩展是否已在system.serviceModel/extensions/behaviorExtensions的扩展集合中注册.参数名称:element

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

Nei*_*eil 2

不幸的是,这对于配置文件来说是不可能的,至少不是以可靠的方式。

原因是,如果您有一个泛型类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">
Run Code Online (Sandbox Code Playgroud)

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

遗憾的是,这让您需要为每个扩展声明具体类型,但这并不是很多工作:

public class MyBehaviorExtensionElement : 
         SimpleBehaviorExtensionElement<MyBehavior> {}
Run Code Online (Sandbox Code Playgroud)

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

<behaviorExtensions>
  <add name="myBehavior" 
    type="BehaviorTest.MyBehaviorExtensionElement, ServiceLibrary"/>      
</behaviorExtensions>
Run Code Online (Sandbox Code Playgroud)