如何使用TinyIOC注册通用接口

10
假设我有一个通用接口和一个通用实现。如何注册所有用法?
具体来说,我有以下内容(为简化起见):
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 - Robert Harvey
不 - 在这个例子中,它将所有的IRepository依赖项(IR<Entity1>,IR<Entity2>等)都注册为AzureRepository<Entity1>。 - seldary
我可以确认这种行为(在v1.2中)- 但显然这是一个错误。 - TeaDrivenDev
1个回答

11

如我在评论中提到的,TinyIoC 在解析开放泛型时存在一个 bug - 它没有将使用不同类型参数解析出的实例区分开来,并且由于所有注册默认都是使用 .AsSingleton(),所以它总是返回第一个泛型类型的实例,无论后续的解析请求是什么。

因此,以下代码无法工作:

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

然而,有一个解决方法 - 将注册设为短暂的:

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

这将为每个分辨率请求创建一个新实例,并正确地遵守类型参数。缺点是,每次使用以前已解析的类型参数请求接口时,您也会获得一个新实例。

编辑

确认。开放式泛型分辨率确实使用SingletonFactory,一旦创建了一个实例,就会始终返回该实例以进行后续的分辨率。它不知道也不关心泛型。为了使其正常工作,需要一个GenericSingletonFactory,它不仅保留单个实例,而且还以要解析的具体类型为键的字典形式保存。

好了,修复起来甚至不难。我只是还不够了解它,无法确定是否完全正确。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接