2017-09-15 14 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) 
    { 
     .... 
    } 
} 

を私は反変インタフェースがIEnumerable<IDomainValidator<object>>の空の配列として解決される問題を抱えているのIEnumerable >としてのIEnumerable >解決されます。私のユニット/統合テストは正常に動作しているので、問題の原因となっている何か他のものが登録されていると仮定しなければなりません。 Autofac [0]

閉鎖型を実装する登録済みの型ではなく、これらの閉鎖型がオブジェクトとして返される方法を判断する方法はありますか?

アップデート1

私はジェネリック型からこれを呼んでいたことに気づき、それが実際に問題を持つ可能性があるものだったということ。 DomainValidation<TDomain>には、ドメインバリデータのリストを説明するオブジェクトもあります。それは以下のようなクラスに注入されている

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

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

} 

このクラスは、技術的に間違っているものですDomainValidationはに登録されています。 IComponentRegistrationがIDomainValidation<SomeClass>の正しいタイプを示しているだけでなく

アップデート2

オブジェクトとして表示され、それはContravariantAdapterを持っているサービスが正しいタイプを示しています。ターゲットは+ Target {Activator = DomainValidation 1(ReflectionActivator)、サービス= [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}と表示されています。問題はどこにあるのでしょうか。今私はなぜこれが起こっているとして固執しています。私は何かが登録されていると仮定していますIDomainValidation<object>

+0

IDomainValidatorを実装するタイプをautofacでどのように登録していますか? –

+0

'.AsClosedTypeOf(typeof(IDomainValidator <>)); 「実現したことの1つは、ジェネリック実装クラスに挿入されていることです。私は質問を更新します。 – cberthold

答えて

0

私は私の問題が何であるか把握することができました。私はbuilder.RegisterSource(new ContravariantRegistrationSource());の使用を示唆した私が使用する別のモジュール(MediatR)を持っています。Contravariantジェネリックインターフェイスではうまく動作しません。一度それを取り除くと、それらのインターフェースは正しいオブジェクトタイプで満たされました。

1

IContravariantInterface<T>(例えば、それがin引数を含む)反変であるので、IContravariantInterface<ConcreteObject>IContravariantInterface<ConcreteSubObject>になくIContravariantInterface<object>にキャストすることができることを意味します。それをIContravariantInterface<object>にキャストすると、消費者はConcreteObject(例えばSystem.String)と全く異なる何かを渡すことができ、これは明らかにIContravariantInterface<ConcreteObject>を実装するクラスを破ることになります。

この意味から、登録されたIContravariantInterface<ConcreteObject>のリストはIContravariantInterface<object>のゼロインスタンスになることは明らかです。これを可能にするにはIContravariantInterface<T>をcovarant(つまりoutキーワードを使用)に変更する必要がありますが、これは入力引数としてTを無効にします。