@@ -17,6 +17,7 @@ public class StructureMapContainerTests : DependencyInjectionSpecificationTests
1717 {
1818 "ResolvesMixedOpenClosedGenericsAsEnumerable" ,
1919 "DisposesInReverseOrderOfCreation" ,
20+ "DisposingScopeDisposesService"
2021 } ;
2122
2223 protected override IServiceProvider CreateServiceProvider ( IServiceCollection services )
@@ -77,6 +78,52 @@ public void CanResolveIEnumerableWithDefaultConstructor()
7778 Assert . NotEmpty ( logger . Factory . Providers ) ;
7879 }
7980
81+ [ Fact ]
82+ public void StructureMap_DisposingScopeDisposesService ( )
83+ {
84+ // StructureMap does not seem to dispose Transient services unless they were created inside of a scope.
85+ // See also:
86+ // Lamar - https://github.com/JasperFx/lamar/blob/adc805705daae241ee1f8bfcd7a46f73530caa83/documentation/documentation/ioc/disposing.md#transients
87+ // Original tests here https://github.com/aspnet/DependencyInjection/blob/930037a4f8b74a9c1e30d881507a05bea0a7c2e0/src/DI.Specification.Tests/DependencyInjectionSpecificationTests.cs#L406
88+
89+ var collection = new ServiceCollection ( ) ;
90+ collection . AddSingleton < IFakeSingletonService , FakeService > ( ) ;
91+ collection . AddScoped < IFakeScopedService , FakeService > ( ) ;
92+ collection . AddTransient < IFakeService , FakeService > ( ) ;
93+
94+ var provider = CreateServiceProvider ( collection ) ;
95+ FakeService disposableService ;
96+ FakeService transient1 ;
97+ FakeService transient2 ;
98+ FakeService singleton ;
99+
100+ // Act and Assert
101+ using ( var scope = provider . CreateScope ( ) )
102+ {
103+ disposableService = ( FakeService ) scope . ServiceProvider . GetService < IFakeScopedService > ( ) ;
104+ transient1 = ( FakeService ) scope . ServiceProvider . GetService < IFakeService > ( ) ;
105+ transient2 = ( FakeService ) scope . ServiceProvider . GetService < IFakeService > ( ) ;
106+ singleton = ( FakeService ) scope . ServiceProvider . GetService < IFakeSingletonService > ( ) ;
107+
108+ Assert . False ( disposableService . Disposed ) ;
109+ Assert . False ( transient1 . Disposed ) ;
110+ Assert . False ( transient2 . Disposed ) ;
111+ Assert . False ( singleton . Disposed ) ;
112+ }
113+
114+ Assert . True ( disposableService . Disposed ) ;
115+ Assert . True ( transient1 . Disposed ) ;
116+ Assert . True ( transient2 . Disposed ) ;
117+ Assert . False ( singleton . Disposed ) ;
118+
119+ var disposableProvider = provider as IDisposable ;
120+ if ( disposableProvider != null )
121+ {
122+ disposableProvider . Dispose ( ) ;
123+ Assert . True ( singleton . Disposed ) ;
124+ }
125+ }
126+
80127 private interface ILoggerProvider { }
81128
82129 private class TestLoggerProvider : ILoggerProvider { }
0 commit comments