Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generic type constraint resolution doesn't see arrays as IEnumerable<> #546

Closed
alansingfield opened this issue Nov 18, 2022 · 5 comments
Closed
Assignees
Labels
bug Something isn't working
Milestone

Comments

@alansingfield
Copy link

Can you help please?

I've created a service with a generic constraint for IEnumerable<> on it - it works as expected with a List<T> but not T[]

public interface IMyThing<T> { }
public interface IMyThing<T, TValue> : IMyThing<T>
    where T : IEnumerable<TValue> { }

public class MyThing<T, TValue> : IMyThing<T, TValue>
    where T : IEnumerable<TValue> { }

var container = new Container();
container.Register(typeof(IMyThing<>), typeof(MyThing<,>), Reuse.ScopedOrSingleton);

// Works - constraint of IEnumerable<TValue> brings int from List<int> into the 2nd generic parameter.
container.Resolve<IMyThing<List<int>>>().ShouldBeOfType<MyThing<List<int>, int>>();

// Works - type is compliant with the generic constraints - would not compile otherwise.
var q = new MyThing<int[], int>();

// Fails when we try to resolve it through the container
container.Resolve<IMyThing<int[]>>().ShouldBeOfType<MyThing<int[], int>>();

Full exception is:

 ArrayDoesntMatch
   Duration: 48 ms

  Message: 
    Test method GenericConstraintResolutionTests2.ArrayDoesntMatch threw exception: 
    DryIoc.ContainerException: code: Error.NoMatchedGenericParamConstraints;
    message: Open-generic service does not match with registered open-generic implementation constraints Sqleze.Tests.GenericConstraintResolutionTests2.MyThing<,> when resolving: resolution root Sqleze.Tests.GenericConstraintResolutionTests2+IMyThing`1[System.Int32[]]
      from container without scope. ---> System.ArgumentException: GenericArguments[0], 'System.Int32[]', on 'Sqleze.Tests.GenericConstraintResolutionTests2+MyThing`2[T,TValue]' violates the constraint of type 'T'. ---> System.TypeLoadException: GenericArguments[0], 'System.Int32[]', on 'Sqleze.Tests.GenericConstraintResolutionTests2+IMyThing`2[T,TValue]' violates the constraint of type parameter 'T'.

  Stack Trace: 
    RuntimeTypeHandle.Instantiate(Type[] inst)
    RuntimeType.MakeGenericType(Type[] instantiation)
    --- End of inner exception stack trace ---
    RuntimeType.ValidateGenericArguments(MemberInfo definition, RuntimeType[] genericArguments, Exception e)
    RuntimeType.MakeGenericType(Type[] instantiation)
    <>c.<GetGeneratedFactoryOrDefault>b__16_0(Type t, Type[] a) line 11598
    ReflectionTools.TryCloseGenericTypeOrMethod[T](T openGenericTypeOrMethod, Type[] typeArgs, Func`3 closeGeneric, Boolean throwCondition, Int32 error, Request r) line 14613
    --- End of inner exception stack trace ---
    ReflectionTools.TryCloseGenericTypeOrMethod[T](T openGenericTypeOrMethod, Type[] typeArgs, Func`3 closeGeneric, Boolean throwCondition, Int32 error, Request r) line 14618
    WithAllDetails.GetGeneratedFactoryOrDefault(Request request, Boolean ifErrorReturnDefault) line 11596
    IContainer.ResolveFactory(Request request) line 902
    Container.ResolveAndCache(Int32 serviceTypeHash, Type serviceType, IfUnresolved ifUnresolved) line 398
    IResolver.Resolve(Type serviceType, IfUnresolved ifUnresolved) line 386
    Resolver.Resolve[TService](IResolver resolver, IfUnresolved ifUnresolved) line 8433
    GenericConstraintResolutionTests2.ArrayDoesntMatch() line 47
@dadhi
Copy link
Owner

dadhi commented Nov 18, 2022

@alansingfield Interesting finding. Thanks. I will check how to fix it.

@dadhi dadhi self-assigned this Nov 18, 2022
@dadhi dadhi added this to the v6.0.0 milestone Nov 18, 2022
dadhi added a commit that referenced this issue Nov 24, 2022
dadhi added a commit that referenced this issue Nov 27, 2022
@dadhi dadhi added the bug Something isn't working label Nov 27, 2022
@dadhi dadhi closed this as completed Nov 27, 2022
@alansingfield
Copy link
Author

Thanks very much!

Will this be backported into v5 or is this a v6-only fix?

@dadhi
Copy link
Owner

dadhi commented Nov 28, 2022

I will backport.

@dadhi dadhi modified the milestones: v6.0.0, v5.3.1 Nov 28, 2022
dadhi added a commit that referenced this issue Nov 28, 2022
@dadhi
Copy link
Owner

dadhi commented Nov 28, 2022

@alansingfield DryIoc v5.3.1 with the fix is out on nuget.

@alansingfield
Copy link
Author

Maksim, I've updated to 5.3.1 and all my tests now pass. Thanks again for your help.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants