2017-09-15 2 views
0
public interface IDomainValidator<in TDomain>{} 

public interface IDomainValidation<TDomain> { 
    void Validate(TDomain domain); 
} 

public class DomainValidation<TDomain> : IDomainValidation<TDomain> 
{ 
    public DomainValidation(IEnumerable<IDomainValidator<TDomain>> validators) 
    { 
     .... 
    } 
} 

Je vais avoir un problème où les interfaces contravariants sont résolues comme un tableau vide de IEnumerable<IDomainValidator<object>>. Mes tests d'unité/d'intégration fonctionnent bien, je dois donc supposer qu'il y a quelque chose d'autre qui est en train d'être enregistré qui cause le problème.Autofac résout IEnumerable <IContravariantInterface <ConcreteObject >> comme IEnumerable <IContravariantInterface <object>> [0]

Est-il possible de déterminer comment ces types fermés sont renvoyés en tant qu'objet au lieu des types enregistrés qui implémentent ces types fermés?

Update 1

j'ai réalisé que j'appelle cela à partir d'un type générique et qu'il était en fait celui qui est susceptible d'être avoir le problème. DomainValidation<TDomain> rencontre également un objet qui explique la liste des validateurs de domaine. DomainValidation est inscrit:

builder.RegisterGeneric(typeof(DomainValidation<>)).As(typeof(IDomainValidation<>));

Il est injecté dans une classe telle que:

public class Implementation 
{ 
    public Implementation(IDomainValidation<SomeClass> validation) {...} 

} 

Cette classe est celle qui est techniquement faux. Il montre comme objet aussi bien

Mise à jour 2

Le IComponentRegistration montre le type de IDomainValidation<SomeClass> correct, il a le ContravariantAdapter et le service montre le type correct. la cible apparaît comme + Target {Activator = DomainValidation 1 (ReflectionActivator), Services = [Flightdocs.Infrastructure.Validation.Domain.IDomainValidation 1[[System.Object, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]], Lifetime = Autofac.Core.Lifetime.CurrentScopeLifetime, Sharing = None, Ownership = OwnedByLifetimeScope} Autofac.Core.IComponentRegistration {Autofac.Core.Registration.ComponentRegistration} Ce que je devine est où le problème est. Maintenant, je suis coincé pour savoir pourquoi cela se produit. Je suppose que quelque chose est en train d'enregistrer comme IDomainValidation<object>

+0

comment inscrivez-vous le (s) type (s) qui implémentent IDomainValidator avec autofac? –

+0

'.AsClosedTypeOf (typeof (IDomainValidator <>)); 'Une chose que j'ai réalisé est qu'il est inséré dans une classe d'implémentation générique. Je vais mettre à jour la question. – cberthold

Répondre

0

J'ai réussi à comprendre quel était mon problème. J'ai un autre module que j'utilise (MediatR) qui a suggéré l'utilisation de builder.RegisterSource(new ContravariantRegistrationSource()); Il ne semble pas fonctionner si bien avec les interfaces génériques Contravariant. Une fois que je l'ai enlevé alors ces interfaces ont été remplies avec le type d'objet correct.

1

Depuis IContravariantInterface<T> est contravariant (par exemple, il contient des arguments in), cela signifie qu'un IContravariantInterface<ConcreteObject> peut être coulé à IContravariantInterface<ConcreteSubObject> mais pas IContravariantInterface<object>. La coulée à IContravariantInterface<object> permettrait à un consommateur de passer dans quelque chose de complètement différent de ConcreteObject (par exemple System.String) qui viendrait évidemment à casser la classe implémentant IContravariantInterface<ConcreteObject>.

Donc, à partir de ce sens, il est évident qu'une liste de IContravariantInterface<ConcreteObject> enregistrée se retrouverait comme 0 instance de IContravariantInterface<object>. Pour être en mesure de le faire, vous devez changer IContravariantInterface<T> en covarant (c'est-à-dire en utilisant le mot-clé out), mais cela désactivera T comme argument d'entrée.