67 lines
2.4 KiB
C#
67 lines
2.4 KiB
C#
using System;
|
|
using System.Collections.Concurrent;
|
|
using System.Collections.Generic;
|
|
|
|
namespace VContainer.Internal
|
|
{
|
|
public class OpenGenericInstanceProvider : IInstanceProvider
|
|
{
|
|
class TypeParametersEqualityComparer : IEqualityComparer<Type[]>
|
|
{
|
|
public bool Equals(Type[] x, Type[] y)
|
|
{
|
|
if (x == null || y == null) return x == y;
|
|
if (x.Length != y.Length) return false;
|
|
|
|
for (var i = 0; i < x.Length; i++)
|
|
{
|
|
if (x[i] != y[i]) return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
public int GetHashCode(Type[] typeParameters)
|
|
{
|
|
var hash = 5381;
|
|
foreach (var typeParameter in typeParameters)
|
|
{
|
|
hash = ((hash << 5) + hash) ^ typeParameter.GetHashCode();
|
|
}
|
|
return hash;
|
|
}
|
|
}
|
|
|
|
readonly Lifetime lifetime;
|
|
readonly Type implementationType;
|
|
readonly IReadOnlyList<IInjectParameter> customParameters;
|
|
|
|
readonly ConcurrentDictionary<Type[], Registration> constructedRegistrations = new ConcurrentDictionary<Type[], Registration>(new TypeParametersEqualityComparer());
|
|
readonly Func<Type[], Registration> createRegistrationFunc;
|
|
|
|
public OpenGenericInstanceProvider(Type implementationType, Lifetime lifetime, List<IInjectParameter> injectParameters)
|
|
{
|
|
this.implementationType = implementationType;
|
|
this.lifetime = lifetime;
|
|
customParameters = injectParameters;
|
|
createRegistrationFunc = CreateRegistration;
|
|
}
|
|
|
|
public Registration GetClosedRegistration(Type closedInterfaceType, Type[] typeParameters)
|
|
{
|
|
return constructedRegistrations.GetOrAdd(typeParameters, createRegistrationFunc);
|
|
}
|
|
|
|
Registration CreateRegistration(Type[] typeParameters)
|
|
{
|
|
var newType = implementationType.MakeGenericType(typeParameters);
|
|
var injector = InjectorCache.GetOrBuild(newType);
|
|
var spawner = new InstanceProvider(injector, customParameters);
|
|
return new Registration(newType, lifetime, new List<Type>(1) { newType }, spawner);
|
|
}
|
|
|
|
public object SpawnInstance(IObjectResolver resolver)
|
|
{
|
|
throw new InvalidOperationException();
|
|
}
|
|
}
|
|
} |