Scope gets lost in Castle Windsor typed factory?

I have following Windsor component registration code in a container with TypedFactoryFacility:

Component
    .For<IMyItemFactory>()
    .AsFactory(f => f.SelectedWith(new MyComponentSelector()))
    .LifestylePerWcfOperation(),

Classes
    .FromAssembly(Assembly.GetExecutingAssembly())
    .BasedOn<IMyItem>()
    .LifestylePerWcfOperation()
    .Configure(c => c.Named(c.Implementation.Name)),

that strives to create autoimplementation of IMyItemFactory. During execution of IMyItemFactory factory method program fails with exception

Castle.MicroKernel.ComponentResolutionException: Could not obtain scope for component SpecificItem. 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)
   at Castle.MicroKernel.Lifestyle.ScopedLifestyleManager.GetScope(CreationContext context)
   at Castle.MicroKernel.Lifestyle.ScopedLifestyleManager.Resolve(CreationContext context, IReleasePolicy releasePolicy)
   at Castle.MicroKernel.Handlers.DefaultHandler.ResolveCore(CreationContext context, Boolean requiresDecommission, Boolean instanceRequired, Burden& burden)
   at Castle.MicroKernel.Handlers.DefaultHandler.Resolve(CreationContext context, Boolean instanceRequired)
   at Castle.MicroKernel.Handlers.AbstractHandler.Resolve(CreationContext context)
   at Castle.MicroKernel.DefaultKernel.ResolveComponent(IHandler handler, Type service, IDictionary additionalArguments, IReleasePolicy policy)
   at Castle.MicroKernel.DefaultKernel.Castle.MicroKernel.IKernelInternal.Resolve(String key, Type service, IDictionary arguments, IReleasePolicy policy)
   at Castle.Facilities.TypedFactory.TypedFactoryComponentResolver.Resolve(IKernelInternal kernel, IReleasePolicy scope)
   at Castle.Facilities.TypedFactory.Internal.TypedFactoryInterceptor.Resolve(IInvocation invocation)
   at Castle.Facilities.TypedFactory.Internal.TypedFactoryInterceptor.Intercept(IInvocation invocation)
   at Castle.DynamicProxy.AbstractInvocation.Proceed()
   at Castle.Proxies.IMyItemFactoryProxy.GetMyItem(String myItemType)

It's confusing as practically every component in the application has WcfOperation scope, so I don't understand how this can happen. I even try to log every registered type with its scope to assert that IMyItem classes have WcfOperation scope – and they have.

Do you have any idea how to debug this?

Edit: I am calling the factory from successfully constructed object with WcfOperation-scope that calls another WcfOperation-scoped services without a problem:

public SomeDataProvider(IElasticsearchClient elasticClient, IMyItemFactory factory)
{
    _elasticClient = elasticClient;

    _factory = factory;
}

async Task SomeMethod()
{
    var someString = await _elasticClient.SomeMethod(); // ok

    var myItem = _factory.GetMyItem(someString); // exception from above

    // ...
}

Upvotes: 1

Views: 1480

Answers (1)

Krzysztof Kozmic
Krzysztof Kozmic

Reputation: 27374

As mentioned in the comments OperationContext.Current was null so technically Windsor was doing the right thing - alerting you to the fact.

Upvotes: 1

Related Questions