mirror of https://github.com/AMT-Cheif/Stylet.git
Fix bug where unbound generics weren't being propagated
This commit is contained in:
parent
3887d38a4a
commit
016eabb1a1
|
@ -15,6 +15,8 @@ namespace StyletIoC
|
||||||
// Needs to be public, or FactoryAssemblyName isn't visible
|
// Needs to be public, or FactoryAssemblyName isn't visible
|
||||||
public class StyletIoCContainer : IContainer, IRegistrationContext
|
public class StyletIoCContainer : IContainer, IRegistrationContext
|
||||||
{
|
{
|
||||||
|
private readonly StyletIoCContainer parent;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Name of the assembly in which abstract factories are built. Use in [assembly: InternalsVisibleTo(StyletIoC.FactoryAssemblyName)] to allow factories created by .ToAbstractFactory() to access internal types
|
/// Name of the assembly in which abstract factories are built. Use in [assembly: InternalsVisibleTo(StyletIoC.FactoryAssemblyName)] to allow factories created by .ToAbstractFactory() to access internal types
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -31,8 +33,6 @@ namespace StyletIoC
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly ConcurrentDictionary<TypeKey, IRegistration> getAllRegistrations = new ConcurrentDictionary<TypeKey, IRegistration>();
|
private readonly ConcurrentDictionary<TypeKey, IRegistration> getAllRegistrations = new ConcurrentDictionary<TypeKey, IRegistration>();
|
||||||
|
|
||||||
private readonly Dictionary<TypeKey, List<UnboundGeneric>> parentUnboundGenerics;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Maps a [type, key] pair, where 'type' is an unbound generic (something like IValidator{}) to something which, given a type, can create an IRegistration for that type.
|
/// Maps a [type, key] pair, where 'type' is an unbound generic (something like IValidator{}) to something which, given a type, can create an IRegistration for that type.
|
||||||
/// So if they've bound an IValidator{} to a an IntValidator, StringValidator, etc, and request an IValidator{string}, one of the UnboundGenerics here can generatr a StringValidator.
|
/// So if they've bound an IValidator{} to a an IntValidator, StringValidator, etc, and request an IValidator{string}, one of the UnboundGenerics here can generatr a StringValidator.
|
||||||
|
@ -72,15 +72,15 @@ namespace StyletIoC
|
||||||
// it's always created by a child, the parent will never get a cached copy. This might get addressed at some point, but the complexity might not
|
// it's always created by a child, the parent will never get a cached copy. This might get addressed at some point, but the complexity might not
|
||||||
// be worth it (especially for such a rarely-used feature).
|
// be worth it (especially for such a rarely-used feature).
|
||||||
|
|
||||||
|
this.parent = parent;
|
||||||
this.registrations = DelegatingDictionary<TypeKey, IRegistrationCollection>.Create(parent.registrations, registration => registration.CloneToContext(this));
|
this.registrations = DelegatingDictionary<TypeKey, IRegistrationCollection>.Create(parent.registrations, registration => registration.CloneToContext(this));
|
||||||
this.parentUnboundGenerics = parent.unboundGenerics;
|
|
||||||
this.builderUppers = DelegatingDictionary<Type, BuilderUpper>.Create(parent.builderUppers);
|
this.builderUppers = DelegatingDictionary<Type, BuilderUpper>.Create(parent.builderUppers);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal StyletIoCContainer()
|
internal StyletIoCContainer()
|
||||||
{
|
{
|
||||||
|
this.parent = null;
|
||||||
this.registrations = DelegatingDictionary<TypeKey, IRegistrationCollection>.Create();
|
this.registrations = DelegatingDictionary<TypeKey, IRegistrationCollection>.Create();
|
||||||
this.parentUnboundGenerics = null;
|
|
||||||
this.builderUppers = DelegatingDictionary<Type, BuilderUpper>.Create();
|
this.builderUppers = DelegatingDictionary<Type, BuilderUpper>.Create();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -273,6 +273,22 @@ namespace StyletIoC
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<UnboundGeneric> UnboundGenericsFromSelfAndParent(TypeKey typeKey)
|
||||||
|
{
|
||||||
|
List<UnboundGeneric> unboundGenerics;
|
||||||
|
if (this.parent != null)
|
||||||
|
unboundGenerics = this.parent.UnboundGenericsFromSelfAndParent(typeKey);
|
||||||
|
else
|
||||||
|
unboundGenerics = new List<UnboundGeneric>();
|
||||||
|
|
||||||
|
List<UnboundGeneric> outUnboundGenerics;
|
||||||
|
if (this.unboundGenerics.TryGetValue(typeKey, out outUnboundGenerics))
|
||||||
|
unboundGenerics.AddRange(outUnboundGenerics);
|
||||||
|
|
||||||
|
return unboundGenerics;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Given a generic type (e.g. IValidator{T}), tries to create a collection of IRegistrations which can implement it from the unbound generic registrations.
|
/// Given a generic type (e.g. IValidator{T}), tries to create a collection of IRegistrations which can implement it from the unbound generic registrations.
|
||||||
/// For example, if someone bound an IValidator{} to Validator{}, and this was called with Validator{T}, the IRegistrationCollection would contain a Validator{T}.
|
/// For example, if someone bound an IValidator{} to Validator{}, and this was called with Validator{T}, the IRegistrationCollection would contain a Validator{T}.
|
||||||
|
@ -290,13 +306,8 @@ namespace StyletIoC
|
||||||
|
|
||||||
Type unboundGenericType = type.GetGenericTypeDefinition();
|
Type unboundGenericType = type.GetGenericTypeDefinition();
|
||||||
|
|
||||||
var unboundGenerics = new List<UnboundGeneric>();
|
|
||||||
List<UnboundGeneric> outUnboundGenerics;
|
|
||||||
var unboundTypeKey = new TypeKey(unboundGenericType, typeKey.Key);
|
var unboundTypeKey = new TypeKey(unboundGenericType, typeKey.Key);
|
||||||
if (this.parentUnboundGenerics != null && this.parentUnboundGenerics.TryGetValue(unboundTypeKey, out outUnboundGenerics))
|
var unboundGenerics = this.UnboundGenericsFromSelfAndParent(unboundTypeKey);
|
||||||
unboundGenerics.AddRange(outUnboundGenerics);
|
|
||||||
if (this.unboundGenerics.TryGetValue(unboundTypeKey, out outUnboundGenerics))
|
|
||||||
unboundGenerics.AddRange(outUnboundGenerics);
|
|
||||||
|
|
||||||
foreach (var unboundGeneric in unboundGenerics)
|
foreach (var unboundGeneric in unboundGenerics)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue