Skip to content

Commit 6a2c016

Browse files
committed
Added logic to support multiple container in .NET 8 DI
Needed to modify basic Castle.Winsor library to support the ability from IHandler interface to get the current kernel associated with the handler. This is needed to find the correct root scope associated with that kernel instance.
1 parent 1830955 commit 6a2c016

16 files changed

+154
-164
lines changed

buildscripts/common.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
<Product>Castle Windsor</Product>
1919
<FileVersion>$(BuildVersionNoSuffix)</FileVersion>
2020
<VersionPrefix>$(BuildVersion)</VersionPrefix>
21-
<AssemblyVersion>6.0.0.0</AssemblyVersion>
21+
<AssemblyVersion>$(BuildVersionMajor).0.0</AssemblyVersion>
2222
<AssemblyTitle>Castle Windsor is best of breed, mature Inversion of Control container available for .NET</AssemblyTitle>
2323
<Authors>Castle Project Contributors</Authors>
2424
<PackageProjectUrl>http://www.castleproject.org/projects/windsor/</PackageProjectUrl>

src/Castle.Windsor.Extensions.DependencyInjection.Tests/CustomAssumptionTests.cs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,7 @@ protected override IServiceProvider BuildServiceProvider(IServiceCollection serv
282282

283283
public class CastleWindsorCustomAssumptionTests : CustomAssumptionTests
284284
{
285+
private WindsorServiceProviderFactory _factory;
285286
private IWindsorContainer _container;
286287

287288
protected override IServiceCollection GetServiceCollection()
@@ -291,9 +292,9 @@ protected override IServiceCollection GetServiceCollection()
291292

292293
protected override IServiceProvider BuildServiceProvider(IServiceCollection serviceCollection)
293294
{
294-
var factory = new WindsorServiceProviderFactory();
295-
_container = factory.CreateBuilder(serviceCollection);
296-
return factory.CreateServiceProvider(_container);
295+
_factory = new WindsorServiceProviderFactory();
296+
_container = _factory.CreateBuilder(serviceCollection);
297+
return _factory.CreateServiceProvider(_container);
297298
}
298299

299300
[Fact]
@@ -351,6 +352,16 @@ public void TryToResolveScopedInOtherThread()
351352

352353
Assert.True(task.Result);
353354
}
355+
356+
357+
protected override void Dispose(bool disposing)
358+
{
359+
base.Dispose(disposing);
360+
if (disposing)
361+
{
362+
_factory.Dispose();
363+
}
364+
}
354365
}
355366

356367
internal class TestService : ITestService

src/Castle.Windsor.Extensions.DependencyInjection.Tests/ResolveFromThreadpoolUnsafe.cs

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,11 @@ public ResolveFromThreadpoolUnsafe_NetStatic() : base(false)
3030
/// NetStatic lifestyle.
3131
/// </summary>
3232
[Fact]
33-
public async Task Cannot_Resolve_LifestyleNetStatic_From_WindsorContainer_NoRootScopeAvailable()
33+
public async Task Can_Resolve_LifestyleNetStatic_From_WindsorContainer_NoRootScopeAvailable()
3434
{
3535
var serviceProvider = new ServiceCollection();
3636
var container = new WindsorContainer();
37-
var f = new WindsorServiceProviderFactory(container);
37+
using var f = new WindsorServiceProviderFactory(container);
3838
f.CreateBuilder(serviceProvider);
3939

4040
container.Register(
@@ -68,14 +68,13 @@ public async Task Cannot_Resolve_LifestyleNetStatic_From_WindsorContainer_NoRoot
6868
{
6969
var task = tcs.Task;
7070
IUserService result = await task;
71-
// The test succeeds if we use standard Castle Windsor Singleton lifestyle instead of the custom NetStatic lifestyle.
71+
//with the fix we can now use correctly a fallback for the root scope so we can access root scope even
72+
//if we are outside of scope
7273
Assert.NotNull(result);
7374
});
7475

7576
// This test will fail if we use NetStatic lifestyle
76-
Assert.NotNull(ex);
77-
Assert.IsType<InvalidOperationException>(ex);
78-
Assert.Equal("No root scope available.", ex.Message);
77+
Assert.Null(ex);
7978

8079
(sp as IDisposable)?.Dispose();
8180
container.Dispose();
@@ -315,7 +314,7 @@ public async Task Cannot_Resolve_LifestyleScoped_From_ServiceProvider()
315314
{
316315
var serviceProvider = new ServiceCollection();
317316
var container = new WindsorContainer();
318-
var f = new WindsorServiceProviderFactory(container);
317+
using var f = new WindsorServiceProviderFactory(container);
319318
f.CreateBuilder(serviceProvider);
320319

321320
container.Register(
@@ -373,7 +372,7 @@ public async Task Cannot_Resolve_LifestyleScoped_From_WindsorContainer()
373372
{
374373
var serviceProvider = new ServiceCollection();
375374
var container = new WindsorContainer();
376-
var f = new WindsorServiceProviderFactory(container);
375+
using var f = new WindsorServiceProviderFactory(container);
377376
f.CreateBuilder(serviceProvider);
378377

379378
container.Register(
@@ -432,7 +431,7 @@ public async Task Can_Resolve_LifestyleScopedToNetServiceScope_From_ServiceProvi
432431
{
433432
var serviceProvider = new ServiceCollection();
434433
var container = new WindsorContainer();
435-
var f = new WindsorServiceProviderFactory(container);
434+
using var f = new WindsorServiceProviderFactory(container);
436435
f.CreateBuilder(serviceProvider);
437436

438437
container.Register(
@@ -475,7 +474,7 @@ public async Task Cannot_Resolve_LifestyleScopedToNetServiceScope_From_WindsorCo
475474
{
476475
var serviceProvider = new ServiceCollection();
477476
var container = new WindsorContainer();
478-
var f = new WindsorServiceProviderFactory(container);
477+
using var f = new WindsorServiceProviderFactory(container);
479478
f.CreateBuilder(serviceProvider);
480479

481480
container.Register(
@@ -540,7 +539,7 @@ public async Task Can_Resolve_LifestyleTransient_From_ServiceProvider()
540539
{
541540
var serviceProvider = new ServiceCollection();
542541
var container = new WindsorContainer();
543-
var f = new WindsorServiceProviderFactory(container);
542+
using var f = new WindsorServiceProviderFactory(container);
544543
f.CreateBuilder(serviceProvider);
545544

546545
container.Register(
@@ -583,7 +582,7 @@ public async Task Can_Resolve_LifestyleTransient_From_WindsorContainer()
583582
{
584583
var serviceProvider = new ServiceCollection();
585584
var container = new WindsorContainer();
586-
var f = new WindsorServiceProviderFactory(container);
585+
using var f = new WindsorServiceProviderFactory(container);
587586
f.CreateBuilder(serviceProvider);
588587

589588
container.Register(
@@ -631,7 +630,7 @@ public async Task Can_Resolve_LifestyleNetTransient_From_ServiceProvider_MemoryL
631630
{
632631
var serviceProvider = new ServiceCollection();
633632
var container = new WindsorContainer();
634-
var f = new WindsorServiceProviderFactory(container);
633+
using var f = new WindsorServiceProviderFactory(container);
635634
f.CreateBuilder(serviceProvider);
636635

637636
container.Register(
@@ -674,7 +673,7 @@ public async Task Cannot_Resolve_LifestyleNetTransient_From_WindsorContainer_NoS
674673
{
675674
var serviceProvider = new ServiceCollection();
676675
var container = new WindsorContainer();
677-
var f = new WindsorServiceProviderFactory(container);
676+
using var f = new WindsorServiceProviderFactory(container);
678677
f.CreateBuilder(serviceProvider);
679678

680679
container.Register(

src/Castle.Windsor.Extensions.DependencyInjection.Tests/WindsorKeyedDependencyInjectionSpecificationTests.cs

Lines changed: 16 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -6,119 +6,43 @@
66

77
namespace Castle.Windsor.Extensions.DependencyInjection.Tests
88
{
9-
public class WindsorKeyedDependencyInjectionSpecificationTests : KeyedDependencyInjectionSpecificationTests
9+
public class WindsorKeyedDependencyInjectionSpecificationTests : KeyedDependencyInjectionSpecificationTests, IDisposable
1010
{
11+
private bool _disposedValue;
12+
private WindsorServiceProviderFactory _factory;
13+
1114
protected override IServiceProvider CreateServiceProvider(IServiceCollection collection)
1215
{
1316
if (collection is TestServiceCollection)
1417
{
15-
var factory = new WindsorServiceProviderFactory();
16-
var container = factory.CreateBuilder(collection);
17-
return factory.CreateServiceProvider(container);
18+
_factory = new WindsorServiceProviderFactory();
19+
var container = _factory.CreateBuilder(collection);
20+
return _factory.CreateServiceProvider(container);
1821
}
1922

2023
return collection.BuildServiceProvider();
2124
}
2225

23-
//[Fact]
24-
//public void ResolveKeyedServiceSingletonInstanceWithAnyKey2()
25-
//{
26-
// var serviceCollection = new ServiceCollection();
27-
// serviceCollection.AddKeyedSingleton<IService, Service>(KeyedService.AnyKey);
28-
29-
// var provider = CreateServiceProvider(serviceCollection);
30-
31-
// Assert.Null(provider.GetService<IService>());
32-
33-
// var serviceKey1 = "some-key";
34-
// var svc1 = provider.GetKeyedService<IService>(serviceKey1);
35-
// Assert.NotNull(svc1);
36-
// Assert.Equal(serviceKey1, svc1.ToString());
37-
38-
// var serviceKey2 = "some-other-key";
39-
// var svc2 = provider.GetKeyedService<IService>(serviceKey2);
40-
// Assert.NotNull(svc2);
41-
// Assert.Equal(serviceKey2, svc2.ToString());
42-
//}
43-
44-
internal interface IService { }
45-
46-
internal class Service : IService
47-
{
48-
private readonly string _id;
49-
50-
public Service() => _id = Guid.NewGuid().ToString();
51-
52-
public Service([ServiceKey] string id) => _id = id;
53-
54-
public override string? ToString() => _id;
55-
}
56-
57-
internal class OtherService
26+
protected virtual void Dispose(bool disposing)
5827
{
59-
public OtherService(
60-
[FromKeyedServices("service1")] IService service1,
61-
[FromKeyedServices("service2")] IService service2)
28+
if (!_disposedValue)
6229
{
63-
Service1 = service1;
64-
Service2 = service2;
65-
}
66-
67-
public IService Service1 { get; }
68-
69-
public IService Service2 { get; }
70-
}
71-
72-
public class FakeService : IFakeEveryService, IDisposable
73-
{
74-
public PocoClass Value { get; set; }
75-
76-
public bool Disposed { get; private set; }
77-
78-
public void Dispose()
79-
{
80-
if (Disposed)
30+
if (disposing)
8131
{
82-
throw new ObjectDisposedException(nameof(FakeService));
32+
_factory?.Dispose();
8333
}
8434

85-
Disposed = true;
35+
_disposedValue = true;
8636
}
8737
}
8838

89-
public interface IFakeEveryService :
90-
IFakeService,
91-
IFakeMultipleService,
92-
IFakeScopedService
93-
{
94-
}
95-
96-
public interface IFakeMultipleService : IFakeService
97-
{
98-
}
99-
100-
public interface IFakeScopedService : IFakeService
101-
{
102-
}
103-
104-
public interface IFakeService
105-
{
106-
}
107-
108-
public class PocoClass
39+
public void Dispose()
10940
{
41+
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
42+
Dispose(disposing: true);
43+
GC.SuppressFinalize(this);
11044
}
11145
}
112-
113-
//public class WindsorKeyedDependencyInjectionSpecificationExplicitContainerTests : KeyedDependencyInjectionSpecificationTests
114-
//{
115-
// protected override IServiceProvider CreateServiceProvider(IServiceCollection collection)
116-
// {
117-
// var factory = new WindsorServiceProviderFactory(new WindsorContainer());
118-
// var container = factory.CreateBuilder(collection);
119-
// return factory.CreateServiceProvider(container);
120-
// }
121-
//}
12246
}
12347

12448
#endif

src/Castle.Windsor.Extensions.DependencyInjection.Tests/WindsorScopedServiceProviderCustomWindsorContainerTests.cs

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,36 @@ namespace Castle.Windsor.Extensions.DependencyInjection.Tests
2121
using Microsoft.Extensions.DependencyInjection.Specification.Fakes;
2222
using Xunit;
2323

24-
public class WindsorScopedServiceProviderCustomWindsorContainerTests : SkippableDependencyInjectionSpecificationTests
24+
public class WindsorScopedServiceProviderCustomWindsorContainerTests : SkippableDependencyInjectionSpecificationTests, IDisposable
2525
{
26+
private bool _disposedValue;
27+
private WindsorServiceProviderFactory _factory;
28+
2629
protected override IServiceProvider CreateServiceProviderImpl(IServiceCollection serviceCollection)
2730
{
28-
var factory = new WindsorServiceProviderFactory(new WindsorContainer());
29-
var container = factory.CreateBuilder(serviceCollection);
30-
return factory.CreateServiceProvider(container);
31+
_factory = new WindsorServiceProviderFactory(new WindsorContainer());
32+
var container = _factory.CreateBuilder(serviceCollection);
33+
return _factory.CreateServiceProvider(container);
34+
}
35+
36+
protected virtual void Dispose(bool disposing)
37+
{
38+
if (!_disposedValue)
39+
{
40+
if (disposing)
41+
{
42+
_factory?.Dispose();
43+
}
44+
45+
_disposedValue = true;
46+
}
47+
}
48+
49+
public void Dispose()
50+
{
51+
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
52+
Dispose(disposing: true);
53+
GC.SuppressFinalize(this);
3154
}
3255

3356
#if NET6_0_OR_GREATER

src/Castle.Windsor.Extensions.DependencyInjection.Tests/WindsorScopedServiceProviderTests.cs

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,36 @@ namespace Castle.Windsor.Extensions.DependencyInjection.Tests
1919
using Microsoft.Extensions.DependencyInjection;
2020
using Microsoft.Extensions.DependencyInjection.Specification;
2121

22-
public class WindsorScopedServiceProviderTests : SkippableDependencyInjectionSpecificationTests
22+
public class WindsorScopedServiceProviderTests : SkippableDependencyInjectionSpecificationTests, IDisposable
2323
{
24+
private bool _disposedValue;
25+
private WindsorServiceProviderFactory _factory;
26+
2427
protected override IServiceProvider CreateServiceProviderImpl(IServiceCollection serviceCollection)
2528
{
26-
var factory = new WindsorServiceProviderFactory();
27-
var container = factory.CreateBuilder(serviceCollection);
28-
return factory.CreateServiceProvider(container);
29+
_factory = new WindsorServiceProviderFactory();
30+
var container = _factory.CreateBuilder(serviceCollection);
31+
return _factory.CreateServiceProvider(container);
32+
}
33+
34+
protected virtual void Dispose(bool disposing)
35+
{
36+
if (!_disposedValue)
37+
{
38+
if (disposing)
39+
{
40+
_factory?.Dispose();
41+
}
42+
43+
_disposedValue = true;
44+
}
45+
}
46+
47+
public void Dispose()
48+
{
49+
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
50+
Dispose(disposing: true);
51+
GC.SuppressFinalize(this);
2952
}
3053
}
3154
}

src/Castle.Windsor.Extensions.DependencyInjection/Castle.Windsor.Extensions.DependencyInjection.csproj

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
<PackageReference Include="Microsoft.Extensions.Options" Version="8.0.0" />
3737
</ItemGroup>
3838

39-
<ItemGroup>
40-
<PackageReference Include="Castle.Windsor" Version="6.0.0" />
41-
</ItemGroup>
39+
<ItemGroup>
40+
<ProjectReference Include="..\Castle.Windsor\Castle.Windsor.csproj" />
41+
</ItemGroup>
4242
</Project>

0 commit comments

Comments
 (0)