Skip to content

Commit

Permalink
adding test for custom singleton lifestyle issue #162
Browse files Browse the repository at this point in the history
  • Loading branch information
ipjohnson committed May 25, 2018
1 parent 05ebc3c commit aae345f
Showing 1 changed file with 96 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using Grace.DependencyInjection;
using Grace.DependencyInjection.Impl.Expressions;
using Grace.DependencyInjection.Lifestyle;
using Grace.Tests.Classes.Simple;
using Xunit;

namespace Grace.Tests.DependencyInjection.Lifestyle
{
public class CustomSingletonLifestyleTests
{
/// <summary>
/// Custom singleton implementation that passes context through during construction
/// </summary>
public class CustomSingletonLifestyle : ICompiledLifestyle
{
private volatile object _singleton;
private readonly object _lockObject = new object();
private ActivationStrategyDelegate _activationDelegate;

/// <summary>
/// Constant expression
/// </summary>
protected Expression ConstantExpression;

public LifestyleType LifestyleType => LifestyleType.Singleton;

public ICompiledLifestyle Clone()
{
return new CustomSingletonLifestyle();
}

public IActivationExpressionResult ProvideLifestyleExpression(IInjectionScope scope, IActivationExpressionRequest request, Func<IActivationExpressionRequest, IActivationExpressionResult> activationExpression)
{
if (ConstantExpression != null)
{
return request.Services.Compiler.CreateNewResult(request, ConstantExpression);
}

// Create new request as we shouldn't carry over anything from the previous request
var newRequest = request.NewRootedRequest(request.ActivationType, scope, true);

_activationDelegate = request.Services.Compiler.CompileDelegate(scope, activationExpression(newRequest));

var singletonMethod = GetType().GetTypeInfo().GetDeclaredMethod("SingletonActivation");

ConstantExpression = Expression.Call(Expression.Constant(this), singletonMethod,
request.Constants.ScopeParameter, request.Constants.RootDisposalScope,
request.Constants.InjectionContextParameter);

return request.Services.Compiler.CreateNewResult(request, ConstantExpression);
}

private object SingletonActivation(IExportLocatorScope scope, IDisposalScope disposalScope,
IInjectionContext context)
{
if (_singleton != null)
{
return _singleton;
}

lock (_lockObject)
{
if (_singleton == null)
{
_singleton = _activationDelegate(scope, disposalScope, context);
}
}

return _singleton;
}
}

[Fact]
public void CustomSingletonTest()
{
var container = new DependencyInjectionContainer();

container.Configure(c => c.Export<DependentService<IBasicService>>().As<IDependentService<IBasicService>>().Lifestyle.Custom(new CustomSingletonLifestyle()));

var instance = container.Locate<IDependentService<IBasicService>>(new { basicService = new BasicService { Count = 5 } });

Assert.NotNull(instance);
Assert.NotNull(instance.Value);
Assert.Equal(5, instance.Value.Count);

var instance2 = container.Locate<IDependentService<IBasicService>>(new { basicService = new BasicService { Count = 15 } });

Assert.Same(instance, instance2);
}
}
}

0 comments on commit aae345f

Please sign in to comment.