2013-03-16 3 views
10

Предположим, у меня есть общий интерфейс и общая реализация. Как зарегистрировать все виды использования?Как зарегистрировать общий интерфейс с использованием TinyIOC

В частности, у меня есть следующие (уменьшенный для простоты):

container.Register<IRepository<Entity1>, AzureRepository<Entity1>>(); 
container.Register<IRepository<Entity2>, AzureRepository<Entity2>>(); 
container.Register<IRepository<Entity3>, AzureRepository<Entity3>>(); 
... 

Или есть более короткий путь:

public interface IRepository<T> where T : TableEntity 
{ 
    T GetById(string partitionKey, string rowKey); 
    void Insert(T entity); 
    void Update(T entity); 
    void Update(string partitionKey, string rowKey, Action<T> updateAction); 
    void Delete(T entity); 
    IQueryable<T> Table { get; } 
} 


public class AzureRepository<T> : IRepository<T> where T : TableEntity 
{ 
    ... 
} 

мне нужно зарегистрировать все реализации один за другим, как так делать ?

+1

Вы хотите что-то ищите? https://github.com/grumpydev/TinyIoC/issues/8 –

+0

Нет. В этом примере он регистрирует все зависимости IRepository (IR , IR и т. д.) как AzureRepository . – seldary

+0

Я могу подтвердить это поведение (в версии 2.1), но это явно ошибка. – TeaDrivenDev

ответ

10

Как упоминалось в моем комментарии, TinyIoC имеет ошибку в разрешении Open Generics - он не хранит разрешенные экземпляры с разными параметрами типа отдельно, и поскольку все регистрации неявно выполняются с .AsSingleton() по умолчанию, он всегда возвращает первый экземпляр типового типа, который был разрешен для всех последующих запросов разрешения.

В связи с этим, следующее не работает:

container.Register(typeof(IRepository<>), typeof(AzureRepository<>)); 

Существует обходной путь, однако, - сделать регистрацию преходящее:

container.Register(typeof(IRepository<>), typeof(AzureRepository<>)).AsMultiInstance(); 

Это создаст новый экземпляр для каждого разрешения запросить и должным образом оценить параметр типа. Недостатком этого является то, что вы также получаете новый экземпляр каждый раз, когда вы запрашиваете интерфейс с параметром типа, который ранее был разрешен.

Редактировать

Подтверждено. В разрешении Open Generics используется SingletonFactory, который после создания экземпляра всегда будет возвращать это для последующих разрешений. Он не знает и не заботится о Generics. Чтобы это работало правильно, потребуется GenericSingletonFactory, который не только сохранит один экземпляр, но и словарь, связанный с конкретным типом, который будет разрешен.

Хорошо, этого даже не было трудно исправить. Я просто недостаточно понимаю об этом, но я уверен, что это действительно все правильно.

Смежные вопросы