2016-11-09 8 views
2

У меня есть interafes классов и выше в моем проекте:Как зарегистрировать типов различного конструктор параметра [Unity IoC]

public interface IRepositoryBase<T> : IDisposable where T : class { } 
public interface IUserRepository : IRepositoryBase<User> { } 
public interface IPaymentRepository : IRepositoryBase<Payment> { } 
public class SecurityContext : DbContext { } 
public class FinanceContext : DbContext { } 

public class RepositoryBase<T> : IRepositoryBase<T> where T : class 
{ 
    public RepositoryBase(DbContext context) { } 
} 

Я пытаюсь придать правильную DbContext к объектам, созданным с IUserRepository х IPaymentRepository интерфейсы:

  • IUserRepository -> должны быть решены в новом RepositoryBase (новый SecurityContext())
  • IPaymentRepository -> должны быть решены как новые RepositoryBase (новый FinanceContext())

Я попробовал этот код без успеха:

container.RegisterType<IUserRepository, RepositoryBase<User>>(
    new InjectionConstructor(container.Resolve<SecurityContext>())); 

... и получил следующую ошибку

типа 'RepositoryBase' не может быть используется как параметр типа «TTo» в общем типе или методе «Microsoft.Practices.Unity.UnityContainerExtensions.RegisterType (Microsoft.Practices.Unity.IUnityContainer, params Microsoft.P ractices.Unity.InjectionMember []). Нет никакого неявного преобразования ссылок из 'RepositoryBase' в 'IUserRepository'.

[EDIT] Я изменил подход, как предложил Георг и это работает прекрасно.

После устранения интерфейсов IUserRepository и IPaymentRepository Я зарегистрировал тип следующим образом:

container.RegisterType<IRepositoryBase<User>, RepositoryBase<User>> 
     (new InjectionConstructor(typeof(SecurityContext))); 

Наконец я должен был изменить свою Услугу делат IRepositoryBase впрыскивается в конструкторе.

public class UserService : IUserService 
{ 
    private readonly IRepositoryBase<User> _repository; 

    public ColaboradorService(IRepositoryBase<User> repository) 
    { 
     _repository = repository; 
    } 
} 
+0

Звучит как проблема ковариации/контравариантности, попробуйте следующее: http://tomasp.net/blog/variance-explained.aspx/ – Charleh

ответ

1

Сообщение об ошибке верное. Ваш класс реализации RepsoitoryBase<T> не реализует IUserRepository, а только его оркестр IRepositoryBase<User>, хотя, поскольку первый ничего не добавляет к последнему, он может предложить эту функцию. Создание этого интерфейса IUserRepository - это нечто большее, чем просто псевдоним IRepositoryBase<User>, и поскольку .NET не позволяет печатать на утке, вы получаете это сообщение об ошибке.

Что вы можете сделать, так это просто зарегистрировать экземпляр как IRepositoryBase<User> вместо IUserRepository. Так как .NET имеет сильные дженерики, первый - это нечто совершенно иное, чем, например, IRepositoryBase<Payment>, так как среда выполнения знает об общих аргументах типа.

+0

Георг, спасибо! Ваше предложение решило проблему конверсии, и с этой точки было легко ввести правильный контекст. спасибо. –