2013-03-16 68 views
10

假设我有一个通用接口和一个通用实现。我如何注册所有用途?如何使用TinyIOC注册通用接口

具体而言,我有以下(减小为简单起见):

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 
{ 
    ... 
} 

是否需要一个接一个地注册所有实施方式中,像这样:

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

或者是有一个较短的方式?

+1

这是你在找什么? https://github.com/grumpydev/TinyIoC/issues/8 – 2013-03-16 14:39:53

+0

否 - 在此示例中,它将所有的IRepository依赖项(IR ,IR 等)注册为AzureRepository 。 – seldary 2013-03-16 19:52:42

+0

我可以证实这种行为(在v1.2中) - 但这显然是一个错误。 – TeaDrivenDev 2013-03-30 00:55:02

回答

10

正如我在评论中提及,TinyIoC在打开泛型的分辨率错误 - 它不守解决实例与不同类型的参数分开,并作为所有注册与.AsSingleton()默认情况下,它总是返回隐式进行为所有后续解析请求解析的泛型类型的第一个实例。

由于这个原因,下面不工作:

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

有一种变通方法,但是 - 做登记瞬态:

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

这将为每个解决方案创建一个新的实例请求并正确地遵守类型参数。这样做的缺点是,每次您使用之前已解决的类型参数请求接口时,您也会获得一个新实例。

编辑

证实。 Open Generics解决方案确实使用了SingletonFactory,一旦它创建了实例,将始终为后续分辨率返回该实例。它不知道或关心泛型。为了能够正常工作,需要GenericSingletonFactory,它不仅保留单个实例,而且还保留一个字典以待解决的具体类型为关键字。

好吧,那不是很难解决。我对此还不够了解,但确定它确实是完全正确的。

相关问题