2

I've just upgraded a solution from .NET 3.5 to .NET 4 In the same time, I've upgraded all external libraries to the latest version, so Castle is now upgraded from 2.5.2 to v3.0

I've some code that register db access that throw now an Exception when I try to resolve:

[Castle.MicroKernel.ComponentResolutionException] {"Could not obtain scope for component DF.MailFlowAdapter. This is most likely either a bug in custom IScopeAccessor or you're trying to access scoped component outside of the scope (like a per-web-request component outside of web request etc)"} Castle.MicroKernel.ComponentResolutionException

The component is registered this way:

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

The problem comes from the PerWcfOperation LifeStyle, but I don't know why: The project is a WCF project and the component is resolved when calling a WCF method. This registration is working fine in the branch that use Castle 2.5.

The exception is thrown when Validating the wcf login/pwd (in a IAuthorizationPolicy that use a UserNamePasswordValidator), because I resolve an IDataAccessAdapter (to check login/pwd in the db).

Other piece of information:

The DataAccessAdapterFacility is an old code that register a component activator, I had to slightly change de code because model.Service changed to 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);
        }
    }
}

And the DataAccessAdapterActivator has in charge to create the object using a connection string in the config file:

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

I think the code with DataAccessAdapterFacility/DataAccessAdapterActivator could be simplify using Factory but it's not the question here :)

So does someone have an idea on why I can't use PerWcfOperation lifestyle ?

4

2 回答 2

1

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

于 2012-05-17T15:05:32.993 回答
0

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

  • 行为发生了变化,在 v2.5 中是依靠短暂的生活方式。但由于不一致(没有关于组件何时为 PerWcfOperation 以及何时为 Transient 的信息),因此已将其删除。
  • 可以使用自定义生活方式范围访问器来做同样的事情

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

于 2012-05-19T07:22:53.623 回答