Skip to content

Commit

Permalink
Merge pull request #546 from seesharper/bugfix/execute-override-only-…
Browse files Browse the repository at this point in the history
…once

Bugfix/execute override only once
  • Loading branch information
seesharper authored Oct 16, 2020
2 parents 6cfa5db + cb0dc3b commit 4714d1b
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 9 deletions.
53 changes: 53 additions & 0 deletions src/LightInject.Tests/ServiceRegistrationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ namespace LightInject.Tests
using System;

using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
using SampleLibrary;

using Xunit;
Expand Down Expand Up @@ -85,6 +87,57 @@ public void GetInstance_OverrideImplementingType_CreateInstanceOfOverriddenImple
Assert.IsAssignableFrom<AnotherFoo>(instance);
}

[Fact]
public void GetInstance_OverrideLifeTime_CallsFactoryOnlyOnce()
{
var container = new ServiceContainer();

container.Register<A>();
container.Register<B>();
container.RegisterSingleton<C>();

container.Override(sr => sr.ServiceType == typeof(C), (f, r) =>
{
r.Lifetime = new PerContainerLifetime();
return r;
});

var a = container.GetInstance<A>();
Assert.Same(a.C, a.B.C);
}

public class A
{
public A(B b, C c)
{
B = b;
C = c;
}

public B B { get; }
public C C { get; }
}

public class B
{
public B(C c)
{
C = c;
}

public C C { get; }
}


public class C
{
public C()
{
Thread.Sleep(100);
}
}


[Fact]
public void ToString_WithAllProperties_ReturnsEasyToReadRepresentation()
{
Expand Down
48 changes: 40 additions & 8 deletions src/LightInject/LightInject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2956,11 +2956,7 @@ public IServiceRegistry Decorate(DecoratorRegistration decoratorRegistration)
/// <inheritdoc/>
public IServiceRegistry Override(Func<ServiceRegistration, bool> serviceSelector, Func<IServiceFactory, ServiceRegistration, ServiceRegistration> serviceRegistrationFactory)
{
var serviceOverride = new ServiceOverride
{
CanOverride = serviceSelector,
ServiceRegistrationFactory = serviceRegistrationFactory,
};
var serviceOverride = new ServiceOverride(serviceSelector, serviceRegistrationFactory);
overrides.Add(serviceOverride);
return this;
}
Expand Down Expand Up @@ -4649,7 +4645,7 @@ private Action<IEmitter> ResolveEmitMethod(ServiceRegistration serviceRegistrati
var serviceOverrides = overrides.Items.Where(so => so.CanOverride(serviceRegistration)).ToArray();
foreach (var serviceOverride in serviceOverrides)
{
serviceRegistration = serviceOverride.ServiceRegistrationFactory(this, serviceRegistration);
serviceRegistration = serviceOverride.Execute(this, serviceRegistration);
}

if (serviceRegistration.Lifetime == null)
Expand Down Expand Up @@ -5014,9 +5010,45 @@ private class Initializer

private class ServiceOverride
{
public Func<ServiceRegistration, bool> CanOverride { get; set; }
private readonly object lockObject = new object();

public Func<IServiceFactory, ServiceRegistration, ServiceRegistration> ServiceRegistrationFactory { get; set; }
private readonly Func<IServiceFactory, ServiceRegistration, ServiceRegistration> serviceRegistrationFactory;

private bool hasExecuted;

public ServiceOverride(Func<ServiceRegistration, bool> canOverride, Func<IServiceFactory, ServiceRegistration, ServiceRegistration> serviceRegistrationFactory)
{
CanOverride = canOverride;
this.serviceRegistrationFactory = serviceRegistrationFactory;
}

public Func<ServiceRegistration, bool> CanOverride { get; }

[ExcludeFromCodeCoverage]
public ServiceRegistration Execute(IServiceFactory serviceFactory, ServiceRegistration serviceRegistration)
{
// Excluded since the double checked lock is virtually impossible to produce.
if (hasExecuted)
{
return serviceRegistration;
}
else
{
lock (lockObject)
{
if (hasExecuted)
{
return serviceRegistration;
}
else
{
hasExecuted = true;
var registration = serviceRegistrationFactory(serviceFactory, serviceRegistration);
return registration;
}
}
}
}
}
}

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 @@
<PropertyGroup>
<TargetFrameworks>netcoreapp2.0;netstandard2.0;netstandard1.6;netstandard1.3;netstandard1.1;net46;net452</TargetFrameworks>
<!-- <TargetFrameworks>netstandard2.0;netcoreapp2.0;netstandard1.6;netstandard1.3;netstandard1.1;net46;net452</TargetFrameworks> -->
<Version>6.3.5</Version>
<Version>6.3.6</Version>
<Authors>Bernhard Richter</Authors>
<PackageProjectUrl>https://www.lightinject.net</PackageProjectUrl>
<RepositoryType>git</RepositoryType>
Expand Down

0 comments on commit 4714d1b

Please sign in to comment.