diff --git a/src/Jab.FunctionalTests.Common/ContainerTests.cs b/src/Jab.FunctionalTests.Common/ContainerTests.cs index 7716a77..efea7c4 100644 --- a/src/Jab.FunctionalTests.Common/ContainerTests.cs +++ b/src/Jab.FunctionalTests.Common/ContainerTests.cs @@ -1,11 +1,10 @@ #nullable enable +using Jab; using System; using System.Collections.Generic; using System.Threading.Tasks; using Xunit; -using Jab; - namespace JabTests { public partial class ContainerTests @@ -548,9 +547,9 @@ public void DisposingScopeDisposesServices() internal partial class DisposingScopeDisposesServicesContainer { } [Fact] - public void DisposingScopeDisposesFactoryGeneratedServicesWhenInstructedTo() + public void DisposingScopeDisposesFactoryGeneratedServices() { - DisposingScopeDisposesFactoryGeneratedServicesWhenInstructedToServicesContainer c = new(); + DisposingScopeDisposesFactoryGeneratedServicesContainer c = new(); var scope = c.CreateScope(); var service = Assert.IsType(scope.GetService()); @@ -559,28 +558,9 @@ public void DisposingScopeDisposesFactoryGeneratedServicesWhenInstructedTo() Assert.Equal(1, service.DisposalCount); } - [ServiceProvider] - [Scoped(typeof(IService), Factory = nameof(CreateDisposableService), AutoDispose = true)] - internal partial class DisposingScopeDisposesFactoryGeneratedServicesWhenInstructedToServicesContainer - { - private static IService CreateDisposableService() => new DisposableServiceImplementation(); - } - - [Fact] - public void DisposingScopeDoesNotDisposeFactoryGeneratedServicesWhenNotInstructedTo() - { - DisposingScopeDoesNotDisposeFactoryGeneratedServicesWhenNotInstructedToServicesContainer c = new(); - var scope = c.CreateScope(); - var service = Assert.IsType(scope.GetService()); - - scope.Dispose(); - - Assert.Equal(0, service.DisposalCount); - } - [ServiceProvider] [Scoped(typeof(IService), Factory = nameof(CreateDisposableService))] - internal partial class DisposingScopeDoesNotDisposeFactoryGeneratedServicesWhenNotInstructedToServicesContainer + internal partial class DisposingScopeDisposesFactoryGeneratedServicesContainer { private static IService CreateDisposableService() => new DisposableServiceImplementation(); } @@ -612,9 +592,9 @@ public async Task DisposingScopeDisposesAsyncServices() internal partial class DisposingScopeDisposesAsyncServicesContainer { } [Fact] - public async Task DisposingScopeDisposesFactoryGeneratedAsyncServicesWhenInstructedTo() + public async Task DisposingScopeDisposesFactoryGeneratedAsyncServices() { - DisposingScopeDisposesFactoryGeneratedAsyncServicesWhenInstructedToServicesContainer c = new(); + DisposingScopeDisposesFactoryGeneratedAsyncServicesContainer c = new(); var scope = c.CreateScope(); var service = Assert.IsType(scope.GetService()); @@ -632,37 +612,9 @@ public async Task DisposingScopeDisposesFactoryGeneratedAsyncServicesWhenInstruc Assert.Equal(1, service.DisposalCount); } - [ServiceProvider] - [Scoped(typeof(IService), Factory = nameof(CreateService), AutoDispose = true)] - internal partial class DisposingScopeDisposesFactoryGeneratedAsyncServicesWhenInstructedToServicesContainer - { - private static IService CreateService() => new AsyncDisposableServiceImplementation(); - } - - [Fact] - public async Task DisposingScopeDoesNotDisposeFactoryGeneratedAsyncServicesWhenNotInstructedTo() - { - DisposingScopeDoesNotDisposeFactoryGeneratedAsyncServicesWhenNotInstructedToServicesContainer c = new(); - var scope = c.CreateScope(); - var service = Assert.IsType(scope.GetService()); - - await scope.DisposeAsync(); - - Assert.Equal(0, service.AsyncDisposalCount); - Assert.Equal(0, service.DisposalCount); - - scope = c.CreateScope(); - service = Assert.IsType(scope.GetService()); - - scope.Dispose(); - - Assert.Equal(0, service.AsyncDisposalCount); - Assert.Equal(0, service.DisposalCount); - } - [ServiceProvider] [Scoped(typeof(IService), Factory = nameof(CreateService))] - internal partial class DisposingScopeDoesNotDisposeFactoryGeneratedAsyncServicesWhenNotInstructedToServicesContainer + internal partial class DisposingScopeDisposesFactoryGeneratedAsyncServicesContainer { private static IService CreateService() => new AsyncDisposableServiceImplementation(); } @@ -686,7 +638,7 @@ internal partial class DisposingProviderDisposesRootScopedServicesContainer { } [Fact] public void DisposingProviderDisposesFactoryGeneratedRootScopedServicesIfInstructedTo() { - DisposingProviderDisposesFactoryGeneratedRootScopedServicesIfInstructedToServicesContainer c = new(); + DisposingProviderDisposesFactoryGeneratedRootScopedServicesContainer c = new(); var service = Assert.IsType(c.GetService()); c.Dispose(); @@ -694,27 +646,9 @@ public void DisposingProviderDisposesFactoryGeneratedRootScopedServicesIfInstruc Assert.Equal(1, service.DisposalCount); } - [ServiceProvider] - [Scoped(typeof(IService), Factory = nameof(GenerateService), AutoDispose = true)] - internal partial class DisposingProviderDisposesFactoryGeneratedRootScopedServicesIfInstructedToServicesContainer - { - private static IService GenerateService() => new DisposableServiceImplementation(); - } - - [Fact] - public void DisposingProviderDoesNotDisposeFactoryGeneratedRootScopedServicesIfNotInstructedTo() - { - DisposingProviderDoesNotDisposeFactoryGeneratedRootScopedServicesIfNotInstructedToServicesContainer c = new(); - var service = Assert.IsType(c.GetService()); - - c.Dispose(); - - Assert.Equal(0, service.DisposalCount); - } - [ServiceProvider] [Scoped(typeof(IService), Factory = nameof(GenerateService))] - internal partial class DisposingProviderDoesNotDisposeFactoryGeneratedRootScopedServicesIfNotInstructedToServicesContainer + internal partial class DisposingProviderDisposesFactoryGeneratedRootScopedServicesContainer { private static IService GenerateService() => new DisposableServiceImplementation(); } @@ -735,9 +669,9 @@ public void DisposingProviderDisposesRootSingletonServices() internal partial class DisposingProviderDisposesRootSingletonServicesContainer { } [Fact] - public void DisposingProviderDisposesFactoryGeneratedRootSingletonServicesWhenInstructedTo() + public void DisposingProviderDisposesFactoryGeneratedRootSingletonServices() { - DisposingProviderDisposesFactoryGeneratedRootSingletonServicesWhenInstructedToServicesContainer c = new(); + DisposingProviderDisposesFactoryGeneratedRootSingletonServicesContainer c = new(); var service = Assert.IsType(c.GetService()); c.Dispose(); @@ -745,27 +679,9 @@ public void DisposingProviderDisposesFactoryGeneratedRootSingletonServicesWhenIn Assert.Equal(1, service.DisposalCount); } - [ServiceProvider] - [Singleton(typeof(IService), Factory = nameof(GetService), AutoDispose = true)] - internal partial class DisposingProviderDisposesFactoryGeneratedRootSingletonServicesWhenInstructedToServicesContainer - { - private static IService GetService() => new DisposableServiceImplementation(); - } - - [Fact] - public void DisposingProviderDoesNotDisposeFactoryGeneratedRootSingletonServicesWhenNotInstructedTo() - { - DisposingProviderDoesNotDisposeFactoryGeneratedRootSingletonServicesWhenNotInstructedToServicesContainer c = new(); - var service = Assert.IsType(c.GetService()); - - c.Dispose(); - - Assert.Equal(0, service.DisposalCount); - } - [ServiceProvider] [Singleton(typeof(IService), Factory = nameof(GetService))] - internal partial class DisposingProviderDoesNotDisposeFactoryGeneratedRootSingletonServicesWhenNotInstructedToServicesContainer + internal partial class DisposingProviderDisposesFactoryGeneratedRootSingletonServicesContainer { private static IService GetService() => new DisposableServiceImplementation(); } @@ -788,9 +704,9 @@ public async Task DisposingProviderDisposesRootSingAsyncServices() internal partial class DisposingProviderDisposesRootSingAsyncServicesContainer { } [Fact] - public async Task DisposingProviderDisposesFactoryGeneratedRootSingAsyncServicesWhenInstructedTo() + public async Task DisposingProviderDisposesFactoryGeneratedRootSingAsyncServices() { - DisposingProviderDisposesFactoryGeneratedRootSingAsyncServicesWhenInstructedToServicesContainer c = new(); + DisposingProviderDisposesFactoryGeneratedRootSingAsyncServicesContainer c = new(); var service = Assert.IsType(c.GetService()); await c.DisposeAsync(); @@ -799,28 +715,9 @@ public async Task DisposingProviderDisposesFactoryGeneratedRootSingAsyncServices Assert.Equal(0, service.DisposalCount); } - [ServiceProvider] - [Scoped(typeof(IService), Factory = nameof(CreateService), AutoDispose = true)] - internal partial class DisposingProviderDisposesFactoryGeneratedRootSingAsyncServicesWhenInstructedToServicesContainer - { - private static IService CreateService() => new AsyncDisposableServiceImplementation(); - } - - [Fact] - public async Task DisposingProviderDoesNotDisposeFactoryGeneratedRootSingAsyncServicesWhenNotInstructedTo() - { - DisposingProviderDoesNotDisposeFactoryGeneratedRootSingAsyncServicesWhenNotInstructedToServicesContainer c = new(); - var service = Assert.IsType(c.GetService()); - - await c.DisposeAsync(); - - Assert.Equal(0, service.AsyncDisposalCount); - Assert.Equal(0, service.DisposalCount); - } - [ServiceProvider] [Scoped(typeof(IService), Factory = nameof(CreateService))] - internal partial class DisposingProviderDoesNotDisposeFactoryGeneratedRootSingAsyncServicesWhenNotInstructedToServicesContainer + internal partial class DisposingProviderDisposesFactoryGeneratedRootSingAsyncServicesContainer { private static IService CreateService() => new AsyncDisposableServiceImplementation(); } @@ -851,7 +748,7 @@ internal partial class DisposingProviderDisposesAllSingletonEnumerableServicesCo [Fact] public async Task DisposingProviderDisposesAllFactoryGeneratedSingletonEnumerableServicesWhenInstructedTo() { - DisposingProviderDisposesAllFactoryGeneratedSingletonEnumerableServicesWhenInstructedToServicesContainer c = new(); + DisposingProviderDisposesAllFactoryGeneratedSingletonEnumerableServicesContainer c = new(); var services = Assert.IsType(c.GetService>()); await c.DisposeAsync(); @@ -863,36 +760,11 @@ public async Task DisposingProviderDisposesAllFactoryGeneratedSingletonEnumerabl } } - [ServiceProvider] - [Scoped(typeof(IService), Factory = nameof(CreateService), AutoDispose = true)] - [Scoped(typeof(IService), Factory = nameof(CreateService), AutoDispose = true)] - [Scoped(typeof(IService), Factory = nameof(CreateService), AutoDispose = true)] - internal partial class DisposingProviderDisposesAllFactoryGeneratedSingletonEnumerableServicesWhenInstructedToServicesContainer - { - private static IService CreateService() => new DisposableServiceImplementation(); - } - - [Fact] - public async Task DisposingProviderDisposesOnlyFactoryGeneratedSingletonEnumerableServicesThatAreRegisteredToDispose() - { - DisposingProviderDisposesOnlyFactoryGeneratedSingletonEnumerableServicesThatAreRegisteredToDisposeServicesContainer c = new(); - var services = Assert.IsType(c.GetService>()); - - await c.DisposeAsync(); - - for (int i = 0; i < services.Length; i++) - { - var disposableService = Assert.IsType(services[i]); - Assert.Equal(i % 2, disposableService.DisposalCount); - } - } - [ServiceProvider] [Scoped(typeof(IService), Factory = nameof(CreateService))] - [Scoped(typeof(IService), Factory = nameof(CreateService), AutoDispose = true)] [Scoped(typeof(IService), Factory = nameof(CreateService))] - [Scoped(typeof(IService), Factory = nameof(CreateService), AutoDispose = true)] - internal partial class DisposingProviderDisposesOnlyFactoryGeneratedSingletonEnumerableServicesThatAreRegisteredToDisposeServicesContainer + [Scoped(typeof(IService), Factory = nameof(CreateService))] + internal partial class DisposingProviderDisposesAllFactoryGeneratedSingletonEnumerableServicesContainer { private static IService CreateService() => new DisposableServiceImplementation(); } @@ -922,9 +794,9 @@ public void DisposingProviderDisposesTransients() internal partial class DisposingProviderDisposesTransientsContainer { } [Fact] - public void DisposingProviderDisposesFactoryGeneratedTransientsIfInstructedTo() + public void DisposingProviderDisposesFactoryGeneratedTransients() { - DisposingProviderDisposesFactoryGeneratedTransientsIfInstructedToContainer c = new(); + DisposingProviderDisposesFactoryGeneratedTransientsContainer c = new(); List services = new(); for (int i = 0; i < 5; i++) { @@ -940,35 +812,9 @@ public void DisposingProviderDisposesFactoryGeneratedTransientsIfInstructedTo() } } - [ServiceProvider] - [Transient(typeof(IService), Factory = nameof(CreateService), AutoDispose = true)] - internal partial class DisposingProviderDisposesFactoryGeneratedTransientsIfInstructedToContainer - { - private static IService CreateService() => new DisposableServiceImplementation(); - } - - [Fact] - public void DisposingProviderDoesNotDisposeFactoryGeneratedTransientsIfNotInstructedTo() - { - DisposingProviderDoesNotDisposeFactoryGeneratedTransientsIfNotInstructedToContainer c = new(); - List services = new(); - for (int i = 0; i < 5; i++) - { - services.Add(c.GetService()); - } - - c.Dispose(); - - foreach (var service in services) - { - var disposableService = Assert.IsType(service); - Assert.Equal(0, disposableService.DisposalCount); - } - } - [ServiceProvider] [Transient(typeof(IService), Factory = nameof(CreateService))] - internal partial class DisposingProviderDoesNotDisposeFactoryGeneratedTransientsIfNotInstructedToContainer + internal partial class DisposingProviderDisposesFactoryGeneratedTransientsContainer { private static IService CreateService() => new DisposableServiceImplementation(); } @@ -999,9 +845,9 @@ public void DisposingScopeDisposesTransients() internal partial class DisposingScopeDisposesTransientsContainer { } [Fact] - public void DisposingScopeDisposesFactoryGeneratedTransientsIfInstructedTo() + public void DisposingScopeDisposesFactoryGeneratedTransients() { - DisposingScopeDisposesFactoryGeneratedTransientsIfInstructedToContainer c = new(); + DisposingScopeDisposesFactoryGeneratedTransientsContainer c = new(); var scope = c.CreateScope(); List services = new(); @@ -1019,45 +865,17 @@ public void DisposingScopeDisposesFactoryGeneratedTransientsIfInstructedTo() } } - [ServiceProvider] - [Transient(typeof(IService), Factory = nameof(CreateService), AutoDispose = true)] - internal partial class DisposingScopeDisposesFactoryGeneratedTransientsIfInstructedToContainer - { - private IService CreateService() => new DisposableServiceImplementation(); - } - - [Fact] - public void DisposingScopeDoesNotDisposeFactoryGeneratedTransientsIfNotInstructedTo() - { - DisposingScopeDoesNotDisposeFactoryGeneratedTransientsIfNotInstructedToContainer c = new(); - var scope = c.CreateScope(); - - List services = new(); - for (int i = 0; i < 5; i++) - { - services.Add(scope.GetService()); - } - - scope.Dispose(); - - foreach (var service in services) - { - var disposableService = Assert.IsType(service); - Assert.Equal(0, disposableService.DisposalCount); - } - } - [ServiceProvider] [Transient(typeof(IService), Factory = nameof(CreateService))] - internal partial class DisposingScopeDoesNotDisposeFactoryGeneratedTransientsIfNotInstructedToContainer + internal partial class DisposingScopeDisposesFactoryGeneratedTransientsContainer { private IService CreateService() => new DisposableServiceImplementation(); } [Fact] - public void DisposingProviderDoesNotDisposeRootSingletonInstanceServicesEvenWithAutoDisposeFlagSet() + public void DisposingProviderDoesNotDisposeRootSingletonInstanceServices() { - DisposingProviderDoesNotDisposeRootSingletonInstanceServicesEvenWithAutoDisposeFlagSetContainer c = new(); + DisposingProviderDoesNotDisposeRootSingletonInstanceServicesContainer c = new(); var service = Assert.IsType(c.GetService()); c.Dispose(); @@ -1067,8 +885,8 @@ public void DisposingProviderDoesNotDisposeRootSingletonInstanceServicesEvenWith } [ServiceProvider] - [Singleton(typeof(IService), Instance = nameof(DisposableServiceImplementation), AutoDispose = true)] - internal partial class DisposingProviderDoesNotDisposeRootSingletonInstanceServicesEvenWithAutoDisposeFlagSetContainer + [Singleton(typeof(IService), Instance = nameof(DisposableServiceImplementation))] + internal partial class DisposingProviderDoesNotDisposeRootSingletonInstanceServicesContainer { internal DisposableServiceImplementation DisposableServiceImplementation { get; } = new DisposableServiceImplementation(); } diff --git a/src/Jab/Attributes.cs b/src/Jab/Attributes.cs index 1c52fa5..f38f7b3 100644 --- a/src/Jab/Attributes.cs +++ b/src/Jab/Attributes.cs @@ -68,14 +68,6 @@ class SingletonAttribute: Attribute public string? Factory { get; set; } - /// - /// If true, the service is considered to be owned by the service provider even though - /// it was created by a factory method. The service provider will dispose the service - /// automatically when it is disposed. If false, the service provider will not dispose - /// the service. The default is false for backwards compatibility reasons. - /// - public bool AutoDispose { get; set; } - public SingletonAttribute(Type serviceType) { ServiceType = serviceType; @@ -105,14 +97,6 @@ class TransientAttribute : Attribute public string? Factory { get; set; } - /// - /// If true, the service is considered to be owned by the service provider even though - /// it was created by a factory method. The service provider will dispose the service - /// automatically when it is disposed. If false, the service provider will not dispose - /// the service. The default is false for backwards compatibility reasons. - /// - public bool AutoDispose { get; set; } - public TransientAttribute(Type serviceType) { ServiceType = serviceType; @@ -142,14 +126,6 @@ class ScopedAttribute : Attribute public string? Factory { get; set; } - /// - /// If true, the service is considered to be owned by the service provider even though - /// it was created by a factory method. The service provider will dispose the service - /// automatically when it is disposed. If false, the service provider will not dispose - /// the service. The default is false for backwards compatibility reasons. - /// - public bool AutoDispose { get; set; } - public ScopedAttribute(Type serviceType) { ServiceType = serviceType; diff --git a/src/Jab/KnownTypes.cs b/src/Jab/KnownTypes.cs index 145c1f0..9b6fce8 100644 --- a/src/Jab/KnownTypes.cs +++ b/src/Jab/KnownTypes.cs @@ -43,7 +43,6 @@ internal class KnownTypes public const string InstanceAttributePropertyName = "Instance"; public const string FactoryAttributePropertyName = "Factory"; public const string RootServicesAttributePropertyName = "RootServices"; - public const string AutoDisposeAttributePropertyName = "AutoDispose"; private const string IAsyncDisposableMetadataName = "System.IAsyncDisposable"; private const string IEnumerableMetadataName = "System.Collections.Generic.IEnumerable`1"; diff --git a/src/Jab/ServiceProviderBuilder.cs b/src/Jab/ServiceProviderBuilder.cs index cb23372..36271ff 100644 --- a/src/Jab/ServiceProviderBuilder.cs +++ b/src/Jab/ServiceProviderBuilder.cs @@ -329,7 +329,7 @@ ServiceCallSite BuiltInCallSite(ServiceCallSite callSite) { var constructedFactoryMethod = factoryMethod.ConstructedFrom.Construct(genericType.TypeArguments, genericType.TypeArgumentNullableAnnotations); - callSite = CreateFactoryCallSite( + callSite = CreateFactoryCallSite( identity, genericType, registration.Lifetime, @@ -337,7 +337,7 @@ ServiceCallSite BuiltInCallSite(ServiceCallSite callSite) memberLocation: registration.MemberLocation, factoryMember: constructedFactoryMethod, context: context, - autoDispose: registration.AutoDispose); + true); } else if (registration.ImplementationType != null) { @@ -491,7 +491,7 @@ static ServiceLifetime GetCommonLifetime(IEnumerable callSites) registration.MemberLocation, factoryMember, context, - registration.AutoDispose); + true); } else { @@ -977,7 +977,6 @@ private bool TryCreateRegistration( string? registrationName = null; string? instanceMemberName = null; string? factoryMemberName = null; - var autoDispose = false; foreach (var namedArgument in attributeData.NamedArguments) { switch (namedArgument.Key) @@ -992,9 +991,6 @@ private bool TryCreateRegistration( case KnownTypes.FactoryAttributePropertyName: factoryMemberName = (string?)namedArgument.Value.Value; break; - case KnownTypes.AutoDisposeAttributePropertyName: - autoDispose = namedArgument.Value.Value is true; - break; } } @@ -1062,8 +1058,7 @@ private bool TryCreateRegistration( instanceMember, factoryMember, attributeData.ApplicationSyntaxReference?.GetSyntax().GetLocation(), - memberLocation, - autoDispose); + memberLocation); return true; } @@ -1182,10 +1177,10 @@ private INamedTypeSymbol ExtractType(TypedConstant typedConstant) var syntax = declaringSyntaxReference.GetSyntax(); return syntax switch { - ParameterSyntax { Type: {} type } => type.GetLocation(), + ParameterSyntax { Type: { } type } => type.GetLocation(), PropertyDeclarationSyntax declarationSyntax => declarationSyntax.Type.GetLocation(), FieldDeclarationSyntax fieldDeclarationSyntax => fieldDeclarationSyntax.Declaration.Type.GetLocation(), - VariableDeclaratorSyntax { Parent: VariableDeclarationSyntax { Type: {} type }} => type.GetLocation(), + VariableDeclaratorSyntax { Parent: VariableDeclarationSyntax { Type: { } type } } => type.GetLocation(), _ => syntax.GetLocation() }; } diff --git a/src/Jab/ServiceRegistration.cs b/src/Jab/ServiceRegistration.cs index 60bb7e0..a8b81a8 100644 --- a/src/Jab/ServiceRegistration.cs +++ b/src/Jab/ServiceRegistration.cs @@ -8,7 +8,6 @@ internal record ServiceRegistration( ISymbol? InstanceMember, ISymbol? FactoryMember, Location? Location, - MemberLocation MemberLocation, - bool AutoDispose); + MemberLocation MemberLocation); internal record RootService(INamedTypeSymbol Service, Location? Location); \ No newline at end of file