Skip to content

Commit

Permalink
Refs: castleproject#646 Castle.Windsor.Extension.DepencencyInjection …
Browse files Browse the repository at this point in the history
…removed null

check on scope cache (AsyncLocal can be null on Threads coming from
Threadpool.UnsafeQueueUserWorkItem, having no null check was also the
original behavior)
  • Loading branch information
AGiorgetti authored and alkampfergit committed Feb 9, 2024
1 parent 77216d1 commit 08ad3dc
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
using Castle.MicroKernel.Registration;
using Castle.Windsor.Extensions.DependencyInjection.Tests.Components;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Threading;
using System.Threading.Tasks;
using Xunit;

namespace Castle.Windsor.Extensions.DependencyInjection.Tests {
public class ResolveFromThreadpoolUnsafe {
[Fact]
public async Task Can_Resolve_From_ServiceProvider() {

var serviceProvider = new ServiceCollection();
var container = new WindsorContainer();
var f = new WindsorServiceProviderFactory(container);
f.CreateBuilder(serviceProvider);

container.Register(
Component.For<IUserService>().ImplementedBy<UserService>()
);

IServiceProvider sp = f.CreateServiceProvider(container);

var actualUserService = sp.GetService<IUserService>();
Assert.NotNull(actualUserService);

/*
ThreadPool.UnsafeQueueUserWorkItem(state => {
// resolving using castle (without scopes) works
var actualUserService = container.Resolve<IUserService>(nameof(UserService));
Assert.NotNull(actualUserService);
}, null);
*/

TaskCompletionSource<IUserService> tcs = new TaskCompletionSource<IUserService>();

ThreadPool.UnsafeQueueUserWorkItem(state => {
try {
var actualUserService = sp.GetService<IUserService>();
Assert.NotNull(actualUserService);
}
catch (Exception ex) {
tcs.SetException(ex);
return;
}
tcs.SetResult(actualUserService);
}, null);

// Wait for the work item to complete.
var task = tcs.Task;
IUserService result = await task;
Assert.NotNull(result);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ internal static class ExtensionContainerScopeCache
/// <exception cref="InvalidOperationException">Thrown when there is no scope available.</exception>
internal static ExtensionContainerScopeBase Current
{
get => current.Value ?? throw new InvalidOperationException("No scope available");
get => current.Value; // ?? throw new InvalidOperationException("No scope available");
set => current.Value = value;
}
}
Expand Down

0 comments on commit 08ad3dc

Please sign in to comment.