Этот вопрос является продолжением моего предыдущего вопроса: Autofac: скрытие нескольких контравариантных реализаций за одним составным .
Я пытаюсь найти границы того, что мы можем сделать с помощью ковариации и контравариантности Autofac. Я заметил, что ContravariantRegistrationSource
в Autofac поддерживает только универсальные интерфейсы с одним универсальным параметром, отмеченным ключевым словом in
. Кажется, это ограничивает полезность этой функции, и мне интересно, есть ли у Autofac другие способы расширения поддержки ковариации и контравариантности.
Должен признать, что я не спрашиваю об этом из-за реального дизайна приложения, над которым я работаю. Я сознательно пытаюсь найти пределы Autofac ради образования.
Итак, рассмотрим следующий интерфейс:
public interface IConverter<in TIn, out TOut>
{
TOut Convert(TIn value);
}
И следующая реализация:
public class ObjectToStringConverter : IConverter<object, string>
{
string IConverter<object, string>.Convert(object value)
{
return value.ToString();
}
}
И следующая регистрация:
var builder = new ContainerBuilder();
builder.RegisterSource(new ContravariantRegistrationSource());
builder.RegisterType<ObjectToStringConverter>()
.As<IConverter<object, string>>();
var container = builder.Build();
С этим дизайном и конфигурацией, я бы ожидал, что смогу сделать это:
// 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>>();
Или позвольте мне выразить это более абстрактно, с учетом следующих определений:
public class A { }
public class B : A { }
public class C : B { }
public class AToCConverter : IConverter<A, C> { ... }
и следующая регистрация:
builder.RegisterType<AToCConverter>()
.As<IConverter<C, A>>();
Я ожидаю, что следующие вызовы будут успешными:
container.Resolve<IConverter<C, A>>();
container.Resolve<IConverter<B, B>>();
container.Resolve<IConverter<A, C>>();
Как мы можем сделать это с Autofac?