Skip to content

Commit

Permalink
Fixed wrong PutInstanceInScope behavior
Browse files Browse the repository at this point in the history
  • Loading branch information
Peter Csajtai committed May 10, 2017
1 parent e69df38 commit 120c03d
Show file tree
Hide file tree
Showing 18 changed files with 67 additions and 39 deletions.
4 changes: 2 additions & 2 deletions appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
artifact: /.*\.nupkg/

environment:
build_version: 2.4.6
build_version: 2.4.7
COVERALLS_REPO_TOKEN:
secure: Q9gcbZnzJ5a0YYF6mkr4QoQylIzeQmVytMnIe4WL7aPtb30SdNes7brLkvnXOirt

Expand Down Expand Up @@ -79,7 +79,7 @@
secure: 2bITagXOj2s3bTJaGXh8/iyWtST8OQOFaMM+0GAKgZts9OjCVCiV7C+E/0SYsM6M

environment:
build_version: 2.4.6
build_version: 2.4.7
COVERALLS_REPO_TOKEN:
secure: Q9gcbZnzJ5a0YYF6mkr4QoQylIzeQmVytMnIe4WL7aPtb30SdNes7brLkvnXOirt

Expand Down
4 changes: 2 additions & 2 deletions src/stashbox.tests/ContainerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ public class TestResolver : Resolver
{
public override bool SupportsMany => true;

public override bool CanUseForResolution(IContainerContext containerContext, TypeInformation typeInfo)
public override bool CanUseForResolution(IContainerContext containerContext, TypeInformation typeInfo, ResolutionInfo resolutionInfo)
{
return typeInfo.Type == typeof(ITest1);
}
Expand All @@ -203,7 +203,7 @@ public class TestResolver2 : Resolver
{
public override bool SupportsMany => true;

public override bool CanUseForResolution(IContainerContext containerContext, TypeInformation typeInfo)
public override bool CanUseForResolution(IContainerContext containerContext, TypeInformation typeInfo, ResolutionInfo resolutionInfo)
{
return typeInfo.Type == typeof(ITest1);
}
Expand Down
25 changes: 23 additions & 2 deletions src/stashbox.tests/DisposeTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -237,8 +237,8 @@ public void DisposeTests_PutInScope_Scoped()
{
using (IStashboxContainer container = new StashboxContainer())
{
container.RegisterType<ITest2, Test2>();
container.RegisterType<Test3>();
container.RegisterScoped<ITest2, Test2>();
container.RegisterScoped<Test3>();

var test = new Test1();

Expand All @@ -256,6 +256,27 @@ public void DisposeTests_PutInScope_Scoped()
}

Assert.IsTrue(test.Disposed);

var test4 = new Test1();

using (var child = container.BeginScope())
{
child.PutInstanceInScope<ITest1>(test4);

var test1 = child.Resolve<ITest1>();
var test2 = child.Resolve<ITest2>();
var test3 = child.Resolve<Test3>();

Assert.AreSame(test4, test1);
Assert.AreSame(test4, test2.Test1);
Assert.AreSame(test4, test3.Test1);

Assert.AreNotSame(test, test1);
Assert.AreNotSame(test, test2.Test1);
Assert.AreNotSame(test, test3.Test1);
}

Assert.IsTrue(test4.Disposed);
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/stashbox/BuildUp/Resolution/DefaultValueResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public override Expression GetExpression(IContainerContext containerContext, Typ
return null;
}

public override bool CanUseForResolution(IContainerContext containerContext, TypeInformation typeInfo) =>
public override bool CanUseForResolution(IContainerContext containerContext, TypeInformation typeInfo, ResolutionInfo resolutionInfo) =>
containerContext.ContainerConfigurator.ContainerConfiguration.OptionalAndDefaultValueInjectionEnabled &&
(typeInfo.HasDefaultValue || typeInfo.Type.GetTypeInfo().IsValueType || typeInfo.Type == typeof(string) || typeInfo.IsMember);
}
Expand Down
2 changes: 1 addition & 1 deletion src/stashbox/BuildUp/Resolution/EnumerableResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public override Expression GetExpression(IContainerContext containerContext, Typ
Expression.NewArrayInit(enumerableType.Type, expressions);
}

public override bool CanUseForResolution(IContainerContext containerContext, TypeInformation typeInfo) =>
public override bool CanUseForResolution(IContainerContext containerContext, TypeInformation typeInfo, ResolutionInfo resolutionInfo) =>
typeInfo.Type.GetEnumerableType() != null;
}
}
2 changes: 1 addition & 1 deletion src/stashbox/BuildUp/Resolution/FuncResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public override Expression[] GetExpressions(IContainerContext containerContext,
return funcExpressions;
}

public override bool CanUseForResolution(IContainerContext containerContext, TypeInformation typeInfo) =>
public override bool CanUseForResolution(IContainerContext containerContext, TypeInformation typeInfo, ResolutionInfo resolutionInfo) =>
typeInfo.Type.IsClosedGenericType() && this.supportedTypes.Contains(typeInfo.Type.GetGenericTypeDefinition());

private ParameterExpression[] PrepareExtraParameters(Type wrappedType, ResolutionInfo resolutionInfo, Type[] args)
Expand Down
2 changes: 1 addition & 1 deletion src/stashbox/BuildUp/Resolution/LazyResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ private Expression CreateLazyExpressionCall(IServiceRegistration serviceRegistra
return Expression.New(constructor, Expression.Lambda(convert));
}

public override bool CanUseForResolution(IContainerContext containerContext, TypeInformation typeInfo) =>
public override bool CanUseForResolution(IContainerContext containerContext, TypeInformation typeInfo, ResolutionInfo resolutionInfo) =>
typeInfo.Type.IsClosedGenericType() && typeInfo.Type.GetGenericTypeDefinition() == typeof(Lazy<>);

private static readonly MethodInfo DelegateCacheMethod = typeof(DelegateCache).GetSingleMethod("CreateLazyDelegate");
Expand Down
2 changes: 1 addition & 1 deletion src/stashbox/BuildUp/Resolution/ParentContainerResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace Stashbox.BuildUp.Resolution
{
internal class ParentContainerResolver : Resolver
{
public override bool CanUseForResolution(IContainerContext containerContext, TypeInformation typeInfo) =>
public override bool CanUseForResolution(IContainerContext containerContext, TypeInformation typeInfo, ResolutionInfo resolutionInfo) =>
containerContext.Container.ParentContainer != null && containerContext.Container.ParentContainer.CanResolve(typeInfo.Type, typeInfo.DependencyName);

public override Expression GetExpression(IContainerContext containerContext, TypeInformation typeInfo, ResolutionInfo resolutionInfo) =>
Expand Down
16 changes: 16 additions & 0 deletions src/stashbox/BuildUp/Resolution/ScopedInstanceResolver.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System.Linq.Expressions;
using Stashbox.Entity;
using Stashbox.Infrastructure;
using Stashbox.Infrastructure.Resolution;

namespace Stashbox.BuildUp.Resolution
{
internal class ScopedInstanceResolver : Resolver
{
public override Expression GetExpression(IContainerContext containerContext, TypeInformation typeInfo, ResolutionInfo resolutionInfo) =>
Expression.Convert(Expression.Call(Constants.ScopeExpression, Constants.GetScopedInstanceMethod, Expression.Constant(typeInfo.Type)), typeInfo.Type);

public override bool CanUseForResolution(IContainerContext containerContext, TypeInformation typeInfo, ResolutionInfo resolutionInfo) =>
resolutionInfo.ResolutionScope.HasScopedInstances && resolutionInfo.ResolutionScope.GetScopedInstanceOrDefault(typeInfo.Type) != null;
}
}
2 changes: 1 addition & 1 deletion src/stashbox/BuildUp/Resolution/TupleResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ internal class TupleResolver : Resolver
typeof(Tuple<,,,,,,,>)
};

public override bool CanUseForResolution(IContainerContext containerContext, TypeInformation typeInfo) =>
public override bool CanUseForResolution(IContainerContext containerContext, TypeInformation typeInfo, ResolutionInfo resolutionInfo) =>
typeInfo.Type.IsClosedGenericType() && this.supportedTypes.Contains(typeInfo.Type.GetGenericTypeDefinition());

public override Expression GetExpression(IContainerContext containerContext, TypeInformation typeInfo, ResolutionInfo resolutionInfo)
Expand Down
2 changes: 1 addition & 1 deletion src/stashbox/BuildUp/Resolution/UnknownTypeResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace Stashbox.BuildUp.Resolution
{
internal class UnknownTypeResolver : Resolver
{
public override bool CanUseForResolution(IContainerContext containerContext, TypeInformation typeInfo) =>
public override bool CanUseForResolution(IContainerContext containerContext, TypeInformation typeInfo, ResolutionInfo resolutionInfo) =>
containerContext.ContainerConfigurator.ContainerConfiguration.UnknownTypeResolutionEnabled &&
typeInfo.Type.IsValidForRegistration();

Expand Down
2 changes: 2 additions & 0 deletions src/stashbox/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ public static class Constants

internal static MethodInfo GetScopedValueMethod = typeof(ScopedLifetime).GetSingleMethod("GetScopedValue", true);

internal static MethodInfo GetScopedInstanceMethod = typeof(IResolutionScope).GetSingleMethod("GetScopedInstanceOrDefault");

internal static Type DisposableType = typeof(IDisposable);

internal static Type FuncType = typeof(Func<>);
Expand Down
3 changes: 2 additions & 1 deletion src/stashbox/Infrastructure/Resolution/IResolverSelector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ public interface IResolverSelector
/// </summary>
/// <param name="containerContext">The container context.</param>
/// <param name="typeInfo">The type info.</param>
/// <param name="resolutionInfo">The resolution info.</param>
/// <returns></returns>
bool CanResolve(IContainerContext containerContext, TypeInformation typeInfo);
bool CanResolve(IContainerContext containerContext, TypeInformation typeInfo, ResolutionInfo resolutionInfo);

/// <summary>
/// Gets an expression built by a selected <see cref="Resolver"/>.
Expand Down
3 changes: 2 additions & 1 deletion src/stashbox/Infrastructure/Resolution/Resolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ public virtual Expression[] GetExpressions(IContainerContext containerContext, T
/// </summary>
/// <param name="containerContext">The container context.</param>
/// <param name="typeInfo">The type info.</param>
/// <param name="resolutionInfo">The info about the actual resolution.</param>
/// <returns>Returns true, if the resolver can be used to activate the requested service, otherwise false.</returns>
public abstract bool CanUseForResolution(IContainerContext containerContext, TypeInformation typeInfo);
public abstract bool CanUseForResolution(IContainerContext containerContext, TypeInformation typeInfo, ResolutionInfo resolutionInfo);
}
}
7 changes: 0 additions & 7 deletions src/stashbox/Resolution/ActivationContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,6 @@ private object Activate(ResolutionInfo resolutionInfo, Type type, object name =
if (type == Constants.ResolverType)
return resolutionInfo.ResolutionScope;

if (resolutionInfo.ResolutionScope.HasScopedInstances)
{
var instance = resolutionInfo.ResolutionScope.GetScopedInstanceOrDefault(type);
if (instance != null)
return instance;
}

var registration = this.containerContext.RegistrationRepository.GetRegistrationOrDefault(type, name);
if (registration != null)
{
Expand Down
7 changes: 0 additions & 7 deletions src/stashbox/Resolution/ResolutionStrategy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,6 @@ public Expression BuildResolutionExpression(IContainerContext containerContext,
if (exprOverride != null)
return exprOverride;

if (resolutionInfo.ResolutionScope.HasScopedInstances)
{
var instance = resolutionInfo.ResolutionScope.GetScopedInstanceOrDefault(typeInformation.Type);
if (instance != null)
return Expression.Constant(instance);
}

var registration = containerContext.RegistrationRepository.GetRegistrationOrDefault(typeInformation, true);
return registration != null ? registration.GetExpression(resolutionInfo, typeInformation.Type) :
this.resolverSelector.GetResolverExpression(containerContext, typeInformation, resolutionInfo);
Expand Down
18 changes: 9 additions & 9 deletions src/stashbox/Resolution/ResolverSelector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,41 +20,41 @@ public ResolverSelector()
this.parentContainerResolver = new ParentContainerResolver();
}

public bool CanResolve(IContainerContext containerContext, TypeInformation typeInfo)
public bool CanResolve(IContainerContext containerContext, TypeInformation typeInfo, ResolutionInfo resolutionInfo)
{
for (var i = 0; i < this.resolverRepository.Lenght; i++)
if (this.resolverRepository.Get(i).CanUseForResolution(containerContext, typeInfo))
if (this.resolverRepository.Get(i).CanUseForResolution(containerContext, typeInfo, resolutionInfo))
return true;

return this.parentContainerResolver.CanUseForResolution(containerContext, typeInfo) ||
this.unknownTypeResolver.CanUseForResolution(containerContext, typeInfo);
return this.parentContainerResolver.CanUseForResolution(containerContext, typeInfo, resolutionInfo) ||
this.unknownTypeResolver.CanUseForResolution(containerContext, typeInfo, resolutionInfo);
}

public Expression GetResolverExpression(IContainerContext containerContext, TypeInformation typeInfo, ResolutionInfo resolutionInfo)
{
for (var i = 0; i < this.resolverRepository.Lenght; i++)
{
var item = this.resolverRepository.Get(i);
if (item.CanUseForResolution(containerContext, typeInfo))
if (item.CanUseForResolution(containerContext, typeInfo, resolutionInfo))
return item.GetExpression(containerContext, typeInfo, resolutionInfo);
}

if (this.parentContainerResolver.CanUseForResolution(containerContext, typeInfo))
if (this.parentContainerResolver.CanUseForResolution(containerContext, typeInfo, resolutionInfo))
return this.parentContainerResolver.GetExpression(containerContext, typeInfo, resolutionInfo);

return this.unknownTypeResolver.CanUseForResolution(containerContext, typeInfo) ? this.unknownTypeResolver.GetExpression(containerContext, typeInfo, resolutionInfo) : null;
return this.unknownTypeResolver.CanUseForResolution(containerContext, typeInfo, resolutionInfo) ? this.unknownTypeResolver.GetExpression(containerContext, typeInfo, resolutionInfo) : null;
}

public Expression[] GetResolverExpressions(IContainerContext containerContext, TypeInformation typeInfo, ResolutionInfo resolutionInfo)
{
for (var i = 0; i < this.resolverRepository.Lenght; i++)
{
var item = this.resolverRepository.Get(i);
if (item.SupportsMany && item.CanUseForResolution(containerContext, typeInfo))
if (item.SupportsMany && item.CanUseForResolution(containerContext, typeInfo, resolutionInfo))
return item.GetExpressions(containerContext, typeInfo, resolutionInfo);
}

return this.parentContainerResolver.CanUseForResolution(containerContext, typeInfo) ? this.parentContainerResolver.GetExpressions(containerContext, typeInfo, resolutionInfo) : null;
return this.parentContainerResolver.CanUseForResolution(containerContext, typeInfo, resolutionInfo) ? this.parentContainerResolver.GetExpressions(containerContext, typeInfo, resolutionInfo) : null;
}

public void AddResolver(Resolver resolver) =>
Expand Down
3 changes: 2 additions & 1 deletion src/stashbox/StashboxContainer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ public bool CanResolve<TFrom>(object name = null) =>
/// <inheritdoc />
public bool CanResolve(Type typeFrom, object name = null) =>
this.registrationRepository.ContainsRegistration(typeFrom, name) ||
this.resolverSelector.CanResolve(this.ContainerContext, new TypeInformation { Type = typeFrom, DependencyName = name });
this.resolverSelector.CanResolve(this.ContainerContext, new TypeInformation { Type = typeFrom, DependencyName = name }, ResolutionInfo.New(this, this));

/// <inheritdoc />
public void Validate()
Expand Down Expand Up @@ -122,6 +122,7 @@ private void RegisterResolvers()
this.resolverSelector.AddResolver(new LazyResolver(this.resolverSelector));
this.resolverSelector.AddResolver(new FuncResolver());
this.resolverSelector.AddResolver(new TupleResolver());
this.resolverSelector.AddResolver(new ScopedInstanceResolver());
this.resolverSelector.AddResolver(new DefaultValueResolver());
}

Expand Down

0 comments on commit 120c03d

Please sign in to comment.