Давайте забудем о Autofac
и попробуем получить коллекцию с чистым C #
IEnumerable<IRepository<BaseProcessorType>> l = new IRepository<BaseProcessorType>[] {
new ActivityRepository()
};
с примером кода, в котором компилятор выдаст ошибку
ОшибкаCS0266 - невозможно неявное преобразование типа ActivityRepository
в IRepository<BaseProcessorType>
.Существует явное преобразование (вам не хватает приведения?)
Основная ошибка заключается в том, что ActivityRepository
не конвертируется в IRepository<BaseProcessorType>
.Чтобы разрешить это приведение, вы должны сделать аргумент T
ковариантным, используя ключевое слово out
public interface IRepository<out T> where T : BaseProcessorType
{}
Но при этом у вас не будет метода с параметром T
Ошибка CS1961 Недопустимая дисперсия: параметр типа T
должен быть контравариантно действительным для IRepository<T>.Add(T)
.T
является ковариантным.
Чтобы понять, почему это запрещено, давайте посмотрим этот пример кода:
IRepository<BaseProcessorType> r = new Activity1Repository();
r.Add(new Activity2());
В этом примере кода r
работает с Activity1
, но вы хотите добавить Activity2
и Activity1
не Activity2
.
Одним из решений было бы не использовать T
в качестве параметра типа, а использовать BaseProcessorType
public interface IRepository<out T> where T : BaseProcessorType
{
Task Add(BaseProcessorType data);
}
Таким образом, чистое решение на C # является действительным.
InДля разрешения IEnumerable<IRepository<BaseProcessorType>>
вам необходимо зарегистрировать ваши типы как IRepository<BaseProcessorType>
.
builder.RegisterAssemblyTypes(dataAccess)
.As(typeof(IRepository<BaseProcessorType>));