Compare commits

..

No commits in common. '3d55222ef0afa76df25e6a84440195adf2d81ce9' and '1b84c307d4f2f1fcb7e2ead4906824b8aa5fb3f0' have entirely different histories.

  1. 5
      LightweightIocContainer.Validation/IocValidator.cs
  2. 2
      LightweightIocContainer.Validation/LightweightIocContainer.Validation.csproj
  3. 2
      LightweightIocContainer/Interfaces/Registrations/IOpenGenericRegistration.cs
  4. 29
      LightweightIocContainer/IocContainer.cs
  5. 2
      LightweightIocContainer/LightweightIocContainer.csproj
  6. 2
      LightweightIocContainer/Registrations/OpenGenericRegistration.cs
  7. 26
      Test.LightweightIocContainer.Validation/IocValidatorTest.cs
  8. 39
      Test.LightweightIocContainer/OpenGenericRegistrationTest.cs

@ -68,14 +68,9 @@ public class IocValidator(IocContainer iocContainer)
foreach (Type genericArgument in genericArguments.Where(g => g.IsGenericParameter))
{
Type[] genericParameterConstraints = genericArgument.GetGenericParameterConstraints();
if (genericParameterConstraints.Any())
{
object mock = Substitute.For(genericParameterConstraints, []);
genericParameters.Add(mock.GetType());
}
else
genericParameters.Add(typeof(object));
}
type = type.MakeGenericType(genericParameters.ToArray());
}

@ -11,7 +11,7 @@
<ImplicitUsings>enable</ImplicitUsings>
<DocumentationFile>LightweightIocContainer.Validation.xml</DocumentationFile>
<VersionPrefix>4.4.0</VersionPrefix>
<VersionSuffix>beta7</VersionSuffix>
<VersionSuffix>beta5</VersionSuffix>
</PropertyGroup>
<PropertyGroup>

@ -9,5 +9,5 @@ namespace LightweightIocContainer.Interfaces.Registrations;
/// </summary>
public interface IOpenGenericRegistration : ITypedRegistration
{
internal Type CreateGenericImplementationType<T>();
}

@ -235,7 +235,10 @@ public class IocContainer : IIocContainer, IIocResolver
switch (result)
{
case true when registration is IOpenGenericRegistration openGenericRegistration:
return (true, new InternalToBeResolvedPlaceholder(openGenericRegistration.CreateGenericImplementationType<T>(), registration, parametersToResolve), null);
{
Type genericImplementationType = openGenericRegistration.ImplementationType.MakeGenericType(typeof(T).GenericTypeArguments);
return (true, new InternalToBeResolvedPlaceholder(genericImplementationType, registration, parametersToResolve), null);
}
case true:
return (true, new InternalToBeResolvedPlaceholder(registeredType, registration, parametersToResolve), null);
}
@ -380,16 +383,21 @@ public class IocContainer : IIocContainer, IIocResolver
/// <returns>A newly created instance of the given <see cref="Type"/></returns>
private T CreateInstance<T>(IRegistration registration, object?[]? arguments)
{
T instance = registration switch
T instance;
if (registration is IOpenGenericRegistration openGenericRegistration)
{
IOpenGenericRegistration openGenericRegistration => Creator.CreateInstance<T>(openGenericRegistration.CreateGenericImplementationType<T>(), arguments),
ISingleTypeRegistration<T> singleTypeRegistration => singleTypeRegistration.FactoryMethod == null
? Creator.CreateInstance<T>(singleTypeRegistration.InterfaceType, arguments)
: singleTypeRegistration.FactoryMethod(this),
ILifestyleProvider { Lifestyle: Lifestyle.Multiton } and IMultitonRegistration multitonRegistration => CreateMultitonInstance<T>(multitonRegistration, arguments),
ITypedRegistration defaultRegistration => Creator.CreateInstance<T>(defaultRegistration.ImplementationType, arguments),
_ => throw new UnknownRegistrationException($"There is no registration of type {registration.GetType().Name}.")
};
//create generic implementation type from generic arguments of T
Type genericImplementationType = openGenericRegistration.ImplementationType.MakeGenericType(typeof(T).GenericTypeArguments);
instance = Creator.CreateInstance<T>(genericImplementationType, arguments);
}
else if (registration is ISingleTypeRegistration<T> singleTypeRegistration)
instance = singleTypeRegistration.FactoryMethod == null ? Creator.CreateInstance<T>(singleTypeRegistration.InterfaceType, arguments) : singleTypeRegistration.FactoryMethod(this);
else if (registration is ILifestyleProvider { Lifestyle: Lifestyle.Multiton } and IMultitonRegistration multitonRegistration)
instance = CreateMultitonInstance<T>(multitonRegistration, arguments);
else if (registration is ITypedRegistration defaultRegistration)
instance = Creator.CreateInstance<T>(defaultRegistration.ImplementationType, arguments);
else
throw new UnknownRegistrationException($"There is no registration of type {registration.GetType().Name}.");
if (registration is ILifestyleProvider { Lifestyle: Lifestyle.Singleton })
_singletons.TryAdd(GetType<T>(registration), instance);
@ -733,7 +741,6 @@ public class IocContainer : IIocContainer, IIocResolver
private Type GetType<T>(IRegistration registration) =>
registration switch
{
IOpenGenericRegistration openGenericRegistration => openGenericRegistration.CreateGenericImplementationType<T>(),
ITypedRegistration typedRegistration => typedRegistration.ImplementationType,
ISingleTypeRegistration<T> singleTypeRegistration => singleTypeRegistration.InterfaceType,
_ => throw new UnknownRegistrationException($"Unknown registration used: {registration.GetType().Name}.")

@ -11,7 +11,7 @@
<ImplicitUsings>enable</ImplicitUsings>
<DocumentationFile>LightweightIocContainer.xml</DocumentationFile>
<VersionPrefix>4.4.0</VersionPrefix>
<VersionSuffix>beta7</VersionSuffix>
<VersionSuffix>beta5</VersionSuffix>
</PropertyGroup>
<PropertyGroup>

@ -29,8 +29,6 @@ internal class OpenGenericRegistration : RegistrationBase, IOpenGenericRegistrat
/// </summary>
public Type ImplementationType { get; }
public Type CreateGenericImplementationType<T>() => ImplementationType.MakeGenericType(typeof(T).GenericTypeArguments);
/// <summary>
/// Validate this <see cref="OpenGenericRegistration"/>
/// </summary>

@ -41,12 +41,6 @@ public class IocValidatorTest
[UsedImplicitly]
public class GenericTest<T> : IGenericTest<T> where T : IConstraint, new();
[UsedImplicitly]
public interface IGenericTestWithoutConstraint<T>;
[UsedImplicitly]
public class GenericTestWithoutConstraint<T> : IGenericTestWithoutConstraint<T>;
[UsedImplicitly]
public interface IGenericTestFactory
{
@ -65,15 +59,6 @@ public class IocValidatorTest
}
}
[UsedImplicitly]
public class GenericParameterWithoutConstraint : IGenericParameter
{
public GenericParameterWithoutConstraint(IGenericTestWithoutConstraint<IParameter> test)
{
}
}
[UsedImplicitly]
private class TestViewModelDontIgnoreDesignTimeCtor : ITest
{
@ -337,17 +322,6 @@ public class IocValidatorTest
validator.Validate();
}
[Test]
public void TestValidateOpenGenericTypeWithoutConstraintAsParameter()
{
IocContainer iocContainer = new();
iocContainer.Register(r => r.AddOpenGenerics(typeof(IGenericTestWithoutConstraint<>), typeof(GenericTestWithoutConstraint<>)));
iocContainer.Register(r => r.Add<IGenericParameter, GenericParameterWithoutConstraint>());
IocValidator validator = new(iocContainer);
validator.Validate();
}
private void AssertNoMatchingConstructorFoundForType<T>(AggregateException aggregateException)
{
Exception exception = aggregateException?.InnerExceptions[0];

@ -21,9 +21,6 @@ public class OpenGenericRegistrationTest
[UsedImplicitly]
public class Constraint : IConstraint;
[UsedImplicitly]
public class AnotherConstraint : IConstraint;
[UsedImplicitly]
[SuppressMessage("ReSharper", "UnusedTypeParameter")]
public interface ITest<T> where T : IConstraint, new();
@ -53,27 +50,15 @@ public class OpenGenericRegistrationTest
}
[UsedImplicitly]
public interface IA
{
ITest<Constraint> Test { get; }
}
public interface IA;
[UsedImplicitly]
public class A(ITest<Constraint> test) : IA
public class A : IA
{
public ITest<Constraint> Test { get; } = test;
}
[UsedImplicitly]
public interface IB
public A(ITest<Constraint> test)
{
ITest<AnotherConstraint> Test { get; }
}
[UsedImplicitly]
public class B(ITest<AnotherConstraint> test) : IB
{
public ITest<AnotherConstraint> Test { get; } = test;
}
}
[SetUp]
@ -141,20 +126,4 @@ public class OpenGenericRegistrationTest
IA a = _iocContainer.Resolve<IA>();
Assert.That(a, Is.TypeOf<A>());
}
[Test]
public void TestOpenGenericTypeAsParameterDifferentGenericParametersResolveDifferentSingletons()
{
_iocContainer.Register(r => r.Add<IA, A>());
_iocContainer.Register(r => r.Add<IB, B>());
_iocContainer.Register(r => r.AddOpenGenerics(typeof(ITest<>), typeof(Test<>), Lifestyle.Singleton));
IA a = _iocContainer.Resolve<IA>();
Assert.That(a, Is.TypeOf<A>());
IB b = _iocContainer.Resolve<IB>();
Assert.That(b, Is.TypeOf<B>());
Assert.That(b.Test, Is.Not.SameAs(a.Test));
}
}
Loading…
Cancel
Save