Questa domanda è un seguito della mia domanda precedente: Autofac: Hiding multiple contravariant implementations behind one composite.Autofac: risoluzione dei tipi di varianti con argomenti di tipo in e out
Sto cercando di trovare i limiti di ciò che possiamo fare con il supporto di covarianza e contravarianza di Autofac. Ho notato che il protocollo ContravariantRegistrationSource
di Autofac supporta solo interfacce generiche con un singolo parametro generico contrassegnato con la parola chiave in
. Questo sembra limitare l'utilità di questa funzionalità e mi chiedo se Autofac abbia altri modi per estendere il supporto della covarianza e della contravarianza.
Devo ammettere che non lo sto chiedendo a causa di un vero design di applicazione su cui sto lavorando. Sto deliberatamente cercando di trovare i limiti di Autofac per l'educazione.
Quindi considerare la seguente interfaccia:
public interface IConverter<in TIn, out TOut>
{
TOut Convert(TIn value);
}
E la seguente implementazione:
public class ObjectToStringConverter : IConverter<object, string>
{
string IConverter<object, string>.Convert(object value)
{
return value.ToString();
}
}
E la seguente registation:
var builder = new ContainerBuilder();
builder.RegisterSource(new ContravariantRegistrationSource());
builder.RegisterType<ObjectToStringConverter>()
.As<IConverter<object, string>>();
var container = builder.Build();
Con questo disegno e la configurazione, mi piacerebbe si aspettano di essere in grado di fare questo:
// 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>>();
Oppure mettiamola più astrattamente, con le definizioni date:
public class A { }
public class B : A { }
public class C : B { }
public class AToCConverter : IConverter<A, C> { ... }
e la seguente iscrizione:
builder.RegisterType<AToCConverter>()
.As<IConverter<C, A>>();
mi aspetterei le seguenti chiamate per avere successo:
container.Resolve<IConverter<C, A>>();
container.Resolve<IConverter<B, B>>();
container.Resolve<IConverter<A, C>>();
Come possiamo farlo con Autofac?
Il controllo di uguaglianza con 1 sta contando il numero di parametri controvarianti; un numero arbitrario di altri parametri (non controvarianti) può ancora essere gestito. Saluti! –