升级到Castle 3.0后,ComponentResolutionException

时间:2012-05-14 07:39:30

标签: c# wcf castle-windsor castle

我刚刚将解决方案从.NET 3.5升级到.NET 4 同时,我已将所有外部库升级到最新版本,因此Castle现在从2.5.2升级到v3.0

我有一些注册数据库访问的代码,当我尝试解决时,它现在抛出异常:

  

[Castle.MicroKernel.ComponentResolutionException] {“无法获取   组件DF.MailFlowAdapter的范围。这很可能是a   自定义IScopeAccessor中的错误或您尝试访问作用域   范围之外的组件(如每个Web请求组件   在Web请求之外   等)“} Castle.MicroKernel.ComponentResolutionException

组件以这种方式注册:

Container
    .AddFacility<WcfFacility>()
    .AddFacility<DataAccessAdapterFacility>()
    .Register(Component
        .For<SD.LLBLGen.Pro.ORMSupportClasses.IDataAccessAdapter>()
        .ImplementedBy<MailFlowAdapter>()
        .LifeStyle.PerWcfOperation())

问题来自PerWcfOperation LifeStyle,但我不知道原因:项目是一个WCF项目,并且在调用WCF方法时解析了该组件。 此注册在使用Castle 2.5的分支中正常工作。

验证wcf login / pwd(在使用UserNamePasswordValidator的IAuthorizationPolicy中)时抛出异常,因为我解析了IDataAccessAdapter(检查db中的login / pwd)。

其他信息:

DataAccessAdapterFacility是一个注册组件激活器的旧代码,我不得不稍微更改de代码,因为model.Service已更改为model.Services:

void Kernel_ComponentModelCreated(ComponentModel model)
{
    foreach (var service in model.Services)
    {
        if (service == typeof(SD.LLBLGen.Pro.ORMSupportClasses.IDataAccessAdapter))
        {
            model.CustomComponentActivator = typeof(DataAccessAdapterActivator);
        }
    }
}

DataAccessAdapterActivator负责使用配置文件中的连接字符串创建对象:

protected override object InternalCreate(CreationContext context)
{
    var connectionString = string.Empty;
    if (ConfigurationManager.ConnectionStrings["Main"] != null)
        connectionString = ConfigurationManager.ConnectionStrings["Main"].ConnectionString;
    return new MailFlowAdapter(connectionString);
}

我认为使用DataAccessAdapterFacility / DataAccessAdapterActivator的代码可以使用Factory进行简化,但这不是问题:)

那么有人知道为什么我不能使用PerWcfOperation生活方式吗?

2 个答案:

答案 0 :(得分:1)

我不相信在调用自定义UserNamePasswordValidator时可以使用OperationContext.Current。是否有可能为该组件使用另一种生活方式?

答案 1 :(得分:0)

好的让我们继续在城堡邮件列表上与Craig Neuwirt进行讨论:

  • 行为发生了变化,在v2.5中又回落了 短暂的生活。但因为它不一致(没有关于何时的信息 这个组件是PerWcfOperation,当它是Transient时) 被删除了。
  • 使用自定义生活方式范围访问器
  • 也可以这样做

我不会在这里发布我的代码,因为一旦你已经阅读了castlecontrib项目中混合生活方式如何完成它是微不足道的