Skip to content

Commit

Permalink
adding custom when condition issue #192
Browse files Browse the repository at this point in the history
  • Loading branch information
ipjohnson committed Sep 3, 2018
1 parent 3e740fc commit 682dc92
Showing 1 changed file with 123 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
using System;
using System.Linq;
using Grace.Data;
using Grace.DependencyInjection;
using Grace.DependencyInjection.Attributes;
using Grace.DependencyInjection.Conditions;
using Grace.Tests.Classes.Attributes;
using Grace.Tests.Classes.Simple;
Expand Down Expand Up @@ -118,5 +121,125 @@ public void WhenInjectedInto_Wrapped()
Assert.NotNull(instance);
Assert.IsType<SimpleObjectDecorator>(instance);
}


#region Complex condition test for issue #192

public interface IMyTestService
{
Func<IBasicService> ServiceAccessor { get; }
}

public class BasicDecorator : IBasicService
{
private IBasicService _basicService;

public BasicDecorator(IBasicService basicService)
{
_basicService = basicService;
}

public int Count
{
get => _basicService.Count;
set => _basicService.Count = value;
}

public int TestMethod()
{
return _basicService.TestMethod();
}
}

public class MyTestService : IMyTestService
{
[Import]
public Func<IBasicService> ServiceAccessor { get; set; }
}

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

container.Configure(c =>
{
c.Export<MyTestService>().As<IMyTestService>().ImportMembers();
c.Export<BasicService>().As<IBasicService>();
c.ExportDecorator(typeof(BasicDecorator)).As(typeof(IBasicService)).When.MeetsCondition(new CustomWhenInjectedInto(typeof(IMyTestService)));
});

var instance = container.Locate<IMyTestService>();

Assert.NotNull(instance);
Assert.NotNull(instance.ServiceAccessor);

var basicInstance = instance.ServiceAccessor();

Assert.NotNull(basicInstance);
Assert.IsType<BasicDecorator>(basicInstance);

var injectInstance = new MyTestService();

container.Inject(injectInstance);

Assert.NotNull(injectInstance);

basicInstance = injectInstance.ServiceAccessor();

Assert.NotNull(basicInstance);
Assert.IsType<BasicDecorator>(basicInstance);
}

public class CustomWhenInjectedInto : ICompiledCondition
{
private readonly Func<Type, bool> _typeTest;

public CustomWhenInjectedInto(params Type[] types)
{
if (types == null) throw new ArgumentNullException(nameof(types));

_typeTest = type => TestTypes(type, types);
}

/// <summary>
/// Test if strategy meets condition at configuration time
/// </summary>
/// <param name="strategy">strategy to test</param>
/// <param name="staticInjectionContext">static injection context</param>
/// <returns>meets condition</returns>
public bool MeetsCondition(IActivationStrategy strategy, StaticInjectionContext staticInjectionContext)
{
var targetInfo =
staticInjectionContext.InjectionStack.FirstOrDefault(
info => info.RequestingStrategy?.StrategyType == ActivationStrategyType.ExportStrategy);

var type = targetInfo?.InjectionType ??
staticInjectionContext.InjectionStack.LastOrDefault()?.LocateType;

return type != null && _typeTest(type);
}

/// <summary>
/// Tests for if one type is based on another
/// </summary>
/// <param name="injectionType"></param>
/// <param name="types"></param>
/// <returns></returns>
protected bool TestTypes(Type injectionType, Type[] types)
{
foreach (var type in types)
{
if (ReflectionService.CheckTypeIsBasedOnAnotherType(injectionType, type))
{
return true;
}
}

return false;
}
}

#endregion
}
}

0 comments on commit 682dc92

Please sign in to comment.