Reputation: 510
Consider following strucure as a registration subject with Autofac 3.0.0:
class Something
{
public int Result { get; set; }
}
class SomethingGood : Something
{
private int _good;
public int GoodResult {
get { return _good + Result; }
set { _good = value; }
}
}
interface IDo<in T> where T : Something
{
int Calculate( T input );
}
class MakeSomethingGood : IDo<SomethingGood>
{
public int Calculate( SomethingGood input ) {
return input.GoodResult;
}
}
class ControlSomething
{
private readonly IDo<Something> _doer;
public ControlSomething( IDo<Something> doer ) {
_doer = doer;
}
public void Show() {
Console.WriteLine( _doer.Calculate( new Something { Result = 5 } ) );
}
}
I'm trying to register concrete type MakeSomethingGood and then resolve it by contravariant interface.
var builder = new ContainerBuilder();
builder.Register( c => new MakeSomethingGood() ).As<IDo<SomethingGood>>();
builder.Register( c => new ControlSomething( c.Resolve<IDo<Something>>() ) ).AsSelf();
var container = builder.Build();
var controller = container.Resolve<ControlSomething>();
... and Resolve
fails because no components found for IDo<Something>
What am I doing wrong?
Thank you
Upvotes: 3
Views: 1084
Reputation: 172835
You register an IDo<SomethingGood>
and try to resolve an IDo<Something>
. How is that ever supposed to work? For this to work, IDo<T>
should be defined as covariant: IDo<out T>
.
Since IDo<in T>
is defined as contravariant (using the in
keyword), you can't simply assign an IDo<SomethingGood>
to IDo<Something>
. This won't compile in C#:
IDo<SomethingGood> good = new MakeSomethingGood();
// Won't compile
IDo<Something> some = good;
And that's why Autofac can't resolve it, even with the ContravariantRegistrationSource
.
Upvotes: 1