【问题标题】:Is a generic BehaviorExtensionElement possible?通用 BehaviorExtensionElement 可能吗?
【发布时间】:2011-06-12 19:39:19
【问题描述】:

我有一些 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/behaviorExtensions。 参数名称:元素

如果我创建一个非泛型 BehaviorExtensionElement 后代,一切都会正常工作,我可以这样做。但现在它困扰着我。 ;)

【问题讨论】:

    标签: c# wcf generics configuration


    【解决方案1】:

    是的,有可能。

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

    指定行为类型时,VersionCulturePublicKeyToken属性必须也被添加.另请注意,必须在每个 ,(逗号)之后恰好有一个空格,并且属性必须按上述顺序出现。

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

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

    【讨论】:

    • 事实并非如此。我有工作行为扩展元素,它们指定没有版本的类型。
    • @TrueWill:我怀疑这些工作元素中的任何一个实际上都是通用的。
    • 你试过这个并成功让它与通用扩展一起工作吗?
    • @TrueWill:你可以打赌我做到了 :) 如果你需要,我可以给你寄一份样品。
    【解决方案2】:

    不幸的是,配置文件无法做到这一点,至少不可靠。

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

    我相信,这是在框架后面部分使用的数据合约序列化中修复的,但配置是旧的。如果您查看 XAML,则可以将类型参数与类型一起使用:

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

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

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

    public class MyBehaviorExtensionElement : 
             SimpleBehaviorExtensionElement<MyBehavior> {}
    

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

    <behaviorExtensions>
      <add name="myBehavior" 
        type="BehaviorTest.MyBehaviorExtensionElement, ServiceLibrary"/>      
    </behaviorExtensions>
    

    【讨论】:

      猜你喜欢
      • 2012-08-27
      • 1970-01-01
      • 2011-11-01
      • 1970-01-01
      • 2011-11-13
      • 1970-01-01
      • 1970-01-01
      • 2023-03-28
      • 2013-11-06
      相关资源
      最近更新 更多