This question is a follow up of my previous question: Autofac: Hiding multiple contravariant implementations behind one composite.
I'm trying to find the boundries of what we can do with Autofac's covariance and contravariance support. I noticed that Autofac's ContravariantRegistrationSource
only supports generic interfaces with a single generic parameter that is marked with the in
keyword. This seems to limit the usefulness of this feature, and I'm wondering if Autofac has other ways in extending the support of covariance and contravariance.
I must admit that I'm not asking this because of a real application design I'm working of. I'm deliberately trying to find Autofac's limits for the sake of education.
So consider the following interface:
public interface IConverter<in TIn, out TOut>
{
TOut Convert(TIn value);
}
And the following implementation:
public class ObjectToStringConverter : IConverter<object, string>
{
string IConverter<object, string>.Convert(object value)
{
return value.ToString();
}
}
And the following registation:
var builder = new ContainerBuilder();
builder.RegisterSource(new ContravariantRegistrationSource());
builder.RegisterType<ObjectToStringConverter>()
.As<IConverter<object, string>>();
var container = builder.Build();
With this design and configuration, I'd expect to be able to do this:
// This call succeeds because IConverter<object, string> is
// explicitly registered.
container.Resolve<IConverter<object, string>>();
// This call fails, although IConverter<string, object> is
// assignable from IConverter<object, string>.
container.Resolve<IConverter<string, object>>();
Or let me put it more abstractly, with the given definitions:
public class A { }
public class B : A { }
public class C : B { }
public class AToCConverter : IConverter<A, C> { ... }
And the following registration:
builder.RegisterType<AToCConverter>()
.As<IConverter<C, A>>();
I would expect the following calls to succeed:
container.Resolve<IConverter<C, A>>();
container.Resolve<IConverter<B, B>>();
container.Resolve<IConverter<A, C>>();
How can we do this with Autofac?