2

I'm trying to register a Generic Interface with multiple Types using Autofac and I like to call:

container.Resolve<Enumerable<IGenericInterface<IInterface>>>(); 

To resolve all the Implementations of IGenericInterface with a type of IInterface.

I already tried to register the concrete classes that have the generic interface with a concrete class as generic interface with the Interface:

builder.Register(r => new TalkToMeLoud())
    .As<IGenericInterface<Hello>>()
    .As<IGenericInterface<Bye>>()
    .As<IGenericInterface<IInterface>>()
    .InstancePerDependency();

But this will throw an error:

An unhandled exception of type 'System.ArgumentException' occurred in Autofac.dll

Additional information: The type 'TestConsoleApp.TalkToMeLoud' is not assignable to service 'TestConsoleApp.IGenericInterface`1[[TestConsoleApp.IInterface, TestConsoleApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]'.

Because this is part of a migration from Unity to Autofac I know this can be done by Unity like this:

Container.ResolveAll(typeof(IGenericInterface<IInterface>))

Does anyone know how to solve this problem?

PS: This is my testproject

Community
  • 1
  • 1
RobertvBraam
  • 120
  • 2
  • 10

1 Answers1

1

The message is quite clear:

The type 'TalkToMeLoud' is not assignable to service 'IGenericInterface'.

In other words, you will either have to:

  • Implement IGenericInterface<IInterface> on TalkToMeLoud or
  • Make IGenericInterface<T> covariant by setting T as out argument. i.e. IGenericInterface<out T>.

The CLR will not be able to cast TalkToMeLoud to IGenericInterface<IInterface> even though it might implement IGenericInterface<Hello> where Hello implements IInterface. If your not familiar with the concept of variance, you might want do a little google search and read answers like this one.

So in your case you probably need to make your interface covarant; this allows you to cast from IGenericInterface<Hello> to IGenericInterface<IInterface>. This only works however when T is only used as output argument in the interface.

Steven
  • 166,672
  • 24
  • 332
  • 435
  • Thanks for the information this is helpfull for me, but do you know why Unity can resolve all the implmentations with IEnumerable> and autofac can't? – RobertvBraam Jan 09 '17 at 08:58
  • @donlobbo: If `IGenericInterface` is not variant, the list that Unity returns should be empty. If not, please update your question to show: 1. your interface definition, 2. your unity configuration 3. which implementations are resolved when you resolve that enumerable and 4 the definition of those implementations. – Steven Jan 09 '17 at 10:06