C# · 12月 31, 2021

c# – 如何使用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>>();…

还是有较短的路?

解决方法 正如我的评论中所提到的,TinyIoC在开放泛型解决方案中有一个错误 – 它不会将分离的不同类型参数的解析实例保持不变,并且由于所有注册都默认使用.AsSingleton()来完成,所以它始终返回为所有后续解决方案请求解决的通用类型的第一个实例.

因此,以下内容不起作用:

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

然而,有一个解决方法 – 使注册瞬变:

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

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

编辑

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

好的,那甚至不是很难解决.我只是不够了解它,但确保它是真的是正确的.