Skip to content

Commit

Permalink
Merge pull request #582 from seesharper/bugfix-dispose-decorators-as-…
Browse files Browse the repository at this point in the history
…singleton

Bugfix dispose decorators as singleton
  • Loading branch information
seesharper committed Dec 29, 2022
2 parents 272c770 + ac1d8af commit 13624c8
Show file tree
Hide file tree
Showing 8 changed files with 92 additions and 17 deletions.
4 changes: 3 additions & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ jobs:
- name: Install .Net Core
uses: actions/setup-dotnet@v2.0.0
with:
dotnet-version: 6.0.400
dotnet-version: |
6.0.x
7.0.x
- name: Install dotnet-script
run: dotnet tool install --global dotnet-script
- name: Install dotnet-ilverify
Expand Down
2 changes: 1 addition & 1 deletion build/build.csx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ using static ReleaseManagement;
[StepDescription("Runs the tests with test coverage")]
Step testcoverage = () =>
{
DotNet.TestWithCodeCoverage(Path.GetDirectoryName(BuildContext.TestProjects[0]), BuildContext.TestCoverageArtifactsFolder, BuildContext.CodeCoverageThreshold, "net6.0");
DotNet.TestWithCodeCoverage(Path.GetDirectoryName(BuildContext.TestProjects[0]), BuildContext.TestCoverageArtifactsFolder, BuildContext.CodeCoverageThreshold, "net7.0");
};

[StepDescription("Runs all the tests for all target frameworks")]
Expand Down
2 changes: 1 addition & 1 deletion global.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"sdk": {
"version": "6.0.100",
"version": "7.0.100",
"rollForward": "latestFeature"
}
}
58 changes: 58 additions & 0 deletions src/LightInject.Tests/DecoratorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -569,6 +569,49 @@ public void GetInstance_DecoratorWithBaseGenericConstraint_AppliesDecorator()
Assert.IsType<FooDecoratorWithBarBaseConstraint<InheritedBar>>(instance);
}

[Fact]
public void GetInstance_DecoratorImplementingDisposable_DisposesDecorator()
{
var container = CreateContainer();
container.Register<IFoo, DisposableFoo>(new PerScopeLifetime());
container.Decorate<IFoo, DisposableFooDecorator>();
DisposableFooDecorator instance = null;
using (var scope = container.BeginScope())
{
instance = (DisposableFooDecorator)scope.GetInstance<IFoo>();
}

Assert.True(instance.Disposed);
}

[Fact]
public void GetInstance_DecoratorImplementingDisposableRegisteredAsSingleton_DisposesDecorator()
{
var container = CreateContainer();
container.Register<IFoo, DisposableFoo>(new PerContainerLifetime());
container.Decorate<IFoo, DisposableFooDecorator>();
DisposableFooDecorator instance = null;


instance = (DisposableFooDecorator)container.GetInstance<IFoo>();
container.Dispose();
Assert.True(instance.Disposed);
}

[Fact]
public void GetInstance_ServicaeAsFactoryAndDecoratorImplementingDisposableRegisteredAsSingleton_DisposesDecorator()
{
var container = CreateContainer();
container.Register<IFoo>(sf => new DisposableFoo(), new PerContainerLifetime());
container.Decorate<IFoo, DisposableFooDecorator>();
DisposableFooDecorator instance = null;


instance = (DisposableFooDecorator)container.GetInstance<IFoo>();
container.Dispose();
Assert.True(instance.Disposed);
}

private IFoo CreateFooWithDependency(IServiceFactory factory)
{
return new FooWithDependency(factory.GetInstance<IBar>());
Expand All @@ -584,4 +627,19 @@ private static FooDecorator GetFooDecorator(IFoo target)
return new FooDecorator(target);
}
}


public class DisposableFooDecorator : IFoo, IDisposable
{
public bool Disposed { get; set; }

public DisposableFooDecorator(IFoo foo)
{
}

public void Dispose()
{
Disposed = true;
}
}
}
2 changes: 1 addition & 1 deletion src/LightInject.Tests/LightInject.Tests.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net7.0</TargetFramework>
<NoWarn>$(NoWarn);CS0579</NoWarn>
<TestTargetFrameworks>net6.0;netstandard2.0</TestTargetFrameworks>
<TestTargetFramework>net6.0</TestTargetFramework>
Expand Down
2 changes: 1 addition & 1 deletion src/LightInject.Tests/ServiceContainerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1136,7 +1136,7 @@ public void CanGetInstance_KnownService_ReturnsTrue(string serviceName)
var canCreateInstance = container.CanGetInstance(typeof(IFoo), serviceName);
Assert.True(canCreateInstance);
}

[Theory]
[MemberData(nameof(StringDataGenerator.NullOrWhiteSpaceData), MemberType = typeof(StringDataGenerator))]
public void CanGetInstance_UnknownService_ReturnFalse(string serviceName)
Expand Down
37 changes: 26 additions & 11 deletions src/LightInject/LightInject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3896,18 +3896,18 @@ private void EmitNewInstance(ServiceRegistration serviceRegistration, IEmitter e
}
}

if (serviceRegistration.Lifetime is PerContainerLifetime && IsNotServiceFactory(serviceRegistration.ServiceType))
{
var closedGenericTrackInstanceMethod = OpenGenericTrackInstanceMethod.MakeGenericMethod(emitter.StackType);
var containerIndex = constants.Add(this);
emitter.PushConstant(containerIndex, typeof(ServiceContainer));
emitter.Emit(OpCodes.Call, closedGenericTrackInstanceMethod);
}
// if (serviceRegistration.Lifetime is PerContainerLifetime && IsNotServiceFactory(serviceRegistration.ServiceType))
// {
// var closedGenericTrackInstanceMethod = OpenGenericTrackInstanceMethod.MakeGenericMethod(emitter.StackType);
// var containerIndex = constants.Add(this);
// emitter.PushConstant(containerIndex, typeof(ServiceContainer));
// emitter.Emit(OpCodes.Call, closedGenericTrackInstanceMethod);
// }

bool IsNotServiceFactory(Type serviceType)
{
return !typeof(IServiceFactory).GetTypeInfo().IsAssignableFrom(serviceType.GetTypeInfo());
}
// bool IsNotServiceFactory(Type serviceType)
// {
// return !typeof(IServiceFactory).GetTypeInfo().IsAssignableFrom(serviceType.GetTypeInfo());
// }
}

private void EmitDecorators(ServiceRegistration serviceRegistration, IEnumerable<DecoratorRegistration> serviceDecorators, IEmitter emitter, Action<IEmitter> decoratorTargetEmitMethod)
Expand Down Expand Up @@ -4697,6 +4697,15 @@ private void EmitNewInstanceWithDecorators(ServiceRegistration serviceRegistrati
EmitNewInstance(serviceRegistration, emitter);
}

if (serviceRegistration.Lifetime is PerContainerLifetime && IsNotServiceFactory(serviceRegistration.ServiceType))
{
var closedGenericTrackInstanceMethod = OpenGenericTrackInstanceMethod.MakeGenericMethod(emitter.StackType);
var containerIndex = constants.Add(this);
emitter.PushConstant(containerIndex, typeof(ServiceContainer));
emitter.Emit(OpCodes.Call, closedGenericTrackInstanceMethod);
}


var processors = initializers.Items.Where(i => i.Predicate(serviceRegistration)).ToArray();
if (processors.Length == 0)
{
Expand All @@ -4723,6 +4732,12 @@ private void EmitNewInstanceWithDecorators(ServiceRegistration serviceRegistrati
}

emitter.Push(instanceVariable);


bool IsNotServiceFactory(Type serviceType)
{
return !typeof(IServiceFactory).GetTypeInfo().IsAssignableFrom(serviceType.GetTypeInfo());
}
}

private int GetInstanceDelegateIndex(ServiceRegistration serviceRegistration, Action<IEmitter> emitMethod)
Expand Down
2 changes: 1 addition & 1 deletion src/LightInject/LightInject.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net6.0;netstandard2.0;netcoreapp3.1;net462</TargetFrameworks>
<Version>6.6.1</Version>
<Version>6.6.2</Version>
<Authors>Bernhard Richter</Authors>
<PackageProjectUrl>https://www.lightinject.net</PackageProjectUrl>
<RepositoryType>git</RepositoryType>
Expand Down

0 comments on commit 13624c8

Please sign in to comment.