question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Castle.Windsor.Extensions.DependencyInjection parallelism issues

See original GitHub issue

@ltines @generik0 thank you for contributing the Castle.Windsor.Extensions.DependencyInjection package. I guess a lot of people are very happy about that!

Since migrating my application to use the ms-di implementation (v5.1), i’ve noticed some potentially serious issues. They occur when running multiple ASP.NET Core Integration Tests in parallel on independent application instances. It seems some dependencies will be shared respectively disposed across HTTP-Request boundaries. At the moment, i can’t say whether this is just a problem when testing or it’s affecting production runtime as well.

My reproducible sample, created using Microsoft guidelines https://docs.microsoft.com/en-us/aspnet/core/test/integration-tests

is attached here InteractionTesting.zip

    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args)
                .Build()
                .Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args)
        {
            return Host.CreateDefaultBuilder(args)
                .UseWindsorContainerServiceProvider()
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                });
        }
    }
    public class Startup
    {
        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
            services
                .AddControllersWithViews()
                .AddControllersAsServices();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app)
        {
            app.UseDeveloperExceptionPage();

            app.UseRouting();

            app.UseEndpoints(endpoints => { endpoints.MapDefaultControllerRoute(); });
        }
    }
    [Route("[controller]")]
    public class DemoController : ControllerBase
    {
        public IActionResult Demo()
        {
            return Ok();
        }
    }

As long as the tests are executed serial they work properly… but if you run them in parallel, they fail for different reasons. image As an example:

2020-11-18 12:56:56 [Debug] Hosting starting
2020-11-18 12:56:56 [Information] User profile is available. Using '"C:\Users\xxx\AppData\Local\ASP.NET\DataProtection-Keys"' as key repository and Windows DPAPI to encrypt keys at rest.
2020-11-18 12:56:56 [Debug] Found key {04f0ed1c-94e8-451e-958f-4a91811712e6}.
2020-11-18 12:56:56 [Debug] Found key {18c67e43-7aa7-42ad-af20-e4c822e82ca7}.
2020-11-18 12:56:56 [Debug] Found key {735d0b36-36d1-4c23-a002-b11d77f2f72e}.
2020-11-18 12:56:56 [Debug] Found key {844a49aa-69e8-4d4a-a7f5-e1df66e6f6d5}.
2020-11-18 12:56:56 [Debug] Found key {a1f9d835-ee2d-4a32-9169-d9660d9b18ff}.
2020-11-18 12:56:56 [Debug] Found key {c612ea1e-d2e2-4615-884d-11445c357eb5}.
2020-11-18 12:56:56 [Debug] Found key {d96d15f6-6878-420a-8384-a14c380f6d24}.
2020-11-18 12:56:56 [Debug] Found key {e0765c4b-4693-408b-9434-75f3058045d1}.
2020-11-18 12:56:56 [Debug] Considering key {a1f9d835-ee2d-4a32-9169-d9660d9b18ff} with expiration date 2021-02-16 11:46:08Z as default key.
2020-11-18 12:56:56 [Debug] Forwarded activator type request from "Microsoft.AspNetCore.DataProtection.XmlEncryption.DpapiXmlDecryptor, Microsoft.AspNetCore.DataProtection, Version=3.1.9.0, Culture=neutral, PublicKeyToken=adb9793829ddae60" to "Microsoft.AspNetCore.DataProtection.XmlEncryption.DpapiXmlDecryptor, Microsoft.AspNetCore.DataProtection, Culture=neutral, PublicKeyToken=adb9793829ddae60"
2020-11-18 12:56:56 [Debug] Decrypting secret element using Windows DPAPI.
2020-11-18 12:56:56 [Debug] Forwarded activator type request from "Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.AuthenticatedEncryptorDescriptorDeserializer, Microsoft.AspNetCore.DataProtection, Version=3.1.9.0, Culture=neutral, PublicKeyToken=adb9793829ddae60" to "Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.AuthenticatedEncryptorDescriptorDeserializer, Microsoft.AspNetCore.DataProtection, Culture=neutral, PublicKeyToken=adb9793829ddae60"
2020-11-18 12:56:56 [Debug] Opening CNG algorithm '"AES"' from provider 'null' with chaining mode CBC.
2020-11-18 12:56:56 [Debug] Opening CNG algorithm '"SHA256"' from provider 'null' with HMAC.
2020-11-18 12:56:56 [Debug] Using key {a1f9d835-ee2d-4a32-9169-d9660d9b18ff} as the default key.
2020-11-18 12:56:56 [Debug] Key ring with default key {a1f9d835-ee2d-4a32-9169-d9660d9b18ff} was loaded during application startup.
2020-11-18 12:56:56 [Debug] Loaded hosting startup assembly "AmazingApi"
2020-11-18 12:56:56 [Information] Application started. Press Ctrl+C to shut down.
2020-11-18 12:56:56 [Information] Hosting environment: "Production"
2020-11-18 12:56:56 [Information] Content root path: "C:\Users\xxx\source\repos\InteractionTesting\AmazingApi"
2020-11-18 12:56:56 [Debug] Hosting started
2020-11-18 12:56:56 [Information] Request starting HTTP/1.1 GET http://localhost/demo
2020-11-18 12:56:56 [Debug] 1 candidate(s) found for the request path '"/demo"'
2020-11-18 12:56:56 [Debug] Endpoint '"AmazingApi.DemoController.Demo (AmazingApi)"' with route pattern '"Demo"' is valid for the request path '"/demo"'
2020-11-18 12:56:56 [Debug] Request matched endpoint '"AmazingApi.DemoController.Demo (AmazingApi)"'
2020-11-18 12:56:56 [Information] Executing endpoint '"AmazingApi.DemoController.Demo (AmazingApi)"'
2020-11-18 12:56:56 [Debug] Registered model binder providers, in the following order: ["Microsoft.AspNetCore.Mvc.ModelBinding.Binders.BinderTypeModelBinderProvider", "Microsoft.AspNetCore.Mvc.ModelBinding.Binders.ServicesModelBinderProvider", "Microsoft.AspNetCore.Mvc.ModelBinding.Binders.BodyModelBinderProvider", "Microsoft.AspNetCore.Mvc.ModelBinding.Binders.HeaderModelBinderProvider", "Microsoft.AspNetCore.Mvc.ModelBinding.Binders.FloatingPointTypeModelBinderProvider", "Microsoft.AspNetCore.Mvc.ModelBinding.Binders.EnumTypeModelBinderProvider", "Microsoft.AspNetCore.Mvc.ModelBinding.Binders.SimpleTypeModelBinderProvider", "Microsoft.AspNetCore.Mvc.ModelBinding.Binders.CancellationTokenModelBinderProvider", "Microsoft.AspNetCore.Mvc.ModelBinding.Binders.ByteArrayModelBinderProvider", "Microsoft.AspNetCore.Mvc.ModelBinding.Binders.FormFileModelBinderProvider", "Microsoft.AspNetCore.Mvc.ModelBinding.Binders.FormCollectionModelBinderProvider", "Microsoft.AspNetCore.Mvc.ModelBinding.Binders.KeyValuePairModelBinderProvider", "Microsoft.AspNetCore.Mvc.ModelBinding.Binders.DictionaryModelBinderProvider", "Microsoft.AspNetCore.Mvc.ModelBinding.Binders.ArrayModelBinderProvider", "Microsoft.AspNetCore.Mvc.ModelBinding.Binders.CollectionModelBinderProvider", "Microsoft.AspNetCore.Mvc.ModelBinding.Binders.ComplexTypeModelBinderProvider"]
2020-11-18 12:56:56 [Information] Executed endpoint '"AmazingApi.DemoController.Demo (AmazingApi)"'
2020-11-18 12:56:56 [Error] An unhandled exception has occurred while executing the request.
System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'Scope was already disposed. This is most likely a bug in the calling code.'.
   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.Resolvers.DefaultDependencyResolver.ResolveFromKernelByType(CreationContext context, ComponentModel model, DependencyModel dependency)
   at Castle.MicroKernel.Resolvers.DefaultDependencyResolver.ResolveFromKernel(CreationContext context, ComponentModel model, DependencyModel dependency)
   at Castle.MicroKernel.Resolvers.DefaultDependencyResolver.TryResolveCore(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model, DependencyModel dependency, Object& value)
   at Castle.MicroKernel.Resolvers.DefaultDependencyResolver.Resolve(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model, DependencyModel dependency)
   at Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.CreateConstructorArguments(ConstructorCandidate constructor, CreationContext context)
   at Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.Instantiate(CreationContext context)
   at Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.InternalCreate(CreationContext context)
   at Castle.MicroKernel.ComponentActivator.AbstractComponentActivator.Create(CreationContext context, Burden burden)
   at Castle.MicroKernel.Lifestyle.AbstractLifestyleManager.CreateInstance(CreationContext context, Boolean trackedExternally)
   at Castle.MicroKernel.Lifestyle.ScopedLifestyleManager.<>n__0(CreationContext context, Boolean trackedExternally)
   at Castle.MicroKernel.Lifestyle.ScopedLifestyleManager.<>c__DisplayClass4_0.<Resolve>b__0(Action`1 afterCreated)
   at Castle.Windsor.Extensions.DependencyInjection.Scope.ExtensionContainerScope.GetCachedInstance(ComponentModel model, ScopedInstanceActivationCallback createInstance)
   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, Arguments additionalArguments, IReleasePolicy policy, Boolean ignoreParentContext)
   at Castle.MicroKernel.DefaultKernel.Castle.MicroKernel.IKernelInternal.Resolve(Type service, Arguments arguments, IReleasePolicy policy, Boolean ignoreParentContext)
   at Castle.MicroKernel.DefaultKernel.Resolve(Type service, Arguments arguments)
   at Castle.Windsor.WindsorContainer.Resolve(Type service)
   at Castle.Windsor.Extensions.DependencyInjection.WindsorScopedServiceProvider.ResolveInstanceOrNull(Type serviceType, Boolean isOptional)
   at Castle.Windsor.Extensions.DependencyInjection.WindsorScopedServiceProvider.GetRequiredService(Type serviceType)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
   at Microsoft.AspNetCore.Mvc.ViewFeatures.SaveTempDataAttribute.CreateInstance(IServiceProvider serviceProvider)
   at Microsoft.AspNetCore.Mvc.Filters.DefaultFilterProvider.ProvideFilter(FilterProviderContext context, FilterItem filterItem)
   at Microsoft.AspNetCore.Mvc.Filters.DefaultFilterProvider.OnProvidersExecuting(FilterProviderContext context)
   at Microsoft.AspNetCore.Mvc.Filters.FilterFactory.CreateUncachedFiltersCore(IFilterProvider[] filterProviders, ActionContext actionContext, List`1 filterItems)
   at Microsoft.AspNetCore.Mvc.Filters.FilterFactory.GetAllFilters(IFilterProvider[] filterProviders, ActionContext actionContext)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvokerCache.GetCachedResult(ControllerContext controllerContext)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvokerProvider.OnProvidersExecuting(ActionInvokerProviderContext context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ActionInvokerFactory.CreateInvoker(ActionContext actionContext)
   at Microsoft.AspNetCore.Mvc.Routing.ActionEndpointFactory.<>c__DisplayClass7_0.<CreateRequestDelegate>b__0(HttpContext context)
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.Invoke(HttpContext httpContext)
--- End of stack trace from previous location where exception was thrown ---
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
2020-11-18 12:56:56 [Information] Request finished in 16.228ms 500 text/plain

If you stick with the built-in service provider and do not use windsor, it works fine even if the tests will be executed in parallel. image

Would you be so kind and take a look at it?

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:1
  • Comments:24 (23 by maintainers)

github_iconTop GitHub Comments

2reactions
nativenoldecommented, Nov 24, 2020

xUnit Workaround: Turn off parallelism inside the assembly [assembly: CollectionBehavior(DisableTestParallelization = true)]

https://xunit.github.io/docs/running-tests-in-parallel.html

2reactions
nativenoldecommented, Nov 18, 2020

image

Read more comments on GitHub >

github_iconTop Results From Across the Web

Castle.Windsor.Extensions.DependencyInjection ...
They occur when running multiple ASP.NET Core Integration Tests in parallel on independent application instances. It seems some dependencies ...
Read more >
Integration for Microsoft.Extensions.DependencyInjection ...
I'm using Castle Windsor in aspnet boilerplate (http://www.aspnetboilerplate.com/) and now want to move to AspNet Core. I faced to the same ...
Read more >
c# - How to resolve Windsor container dependencies for a ...
UseWindsorContainerServiceProvider is an extension method provided from the NuGet package Castle.Windsor.Extensions.DependencyInjection .
Read more >
Automatic factory with Microsoft.Extensions ...
Dependency injection (DI) is a great pattern, which can really help make your code cleaner, more decoupled and more testable. There are many...
Read more >
Dependency Injection in WCF using Castle Windsor
To solve this problem developer ends up writing two constructors one is default and the other one is parameterized.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found