如何添加通用依赖注入[重复]

Posted

技术标签:

【中文标题】如何添加通用依赖注入[重复]【英文标题】:How to add a generic dependency injection [duplicate] 【发布时间】:2017-08-22 14:31:35 【问题描述】:

开发一个只读的 api 服务并利用泛型将操作打包到基于约定的流程中。

存储库接口:

public interface IRepository<TIdType,TEntityType> where TEntityType:class 
   Task<EntityMetadata<TIdType>> GetMetaAsync();

存储库实现:

public class Repository<TIdType,TEntityType> : IRepository<TIdType,TEntityType> where TEntityType:class 
   public Repository(string connectionString)  // initialization 
   public async Tas<EntityMetadata<TIdType>> GetMetaAsync()  // implementation   

Startup.cs -&gt; ConfigureServices

services.AddSingleton<IRepository<int, Employee>> ( p=> new Repository<int, Employee>(connectionString));
services.AddSingleton<IRepository<int, Department>> ( p=> new Repository<int, Department>(connectionString));
// and so on

控制器:

public class EmployeeController : Controller 
   public EmployeeController(IRepository<int,Employee> repo) //stuff

我目前正在为ConfigureServices 中的所有类型的实体类型重复存储库实现。有没有办法让这个也通用?

services.AddSingleton<IRepository<TIdType, TEntityType>> ( p=> new Repository<TIdType, TEntityType>(connectionString));

那么在控制器的构造函数调用中可以自动获取相关的仓库吗?

更新 1:不是duplicate:

    存储库实现没有默认构造函数 由于它没有默认构造函数,我无法提供链接问题中给出的解决方案。 尝试services.AddScoped(typeof(IRepository&lt;&gt;), ...) 时出现错误Using the generic type 'IRepostiory&lt;TIdType,TEntityType&gt;' requires 2 type arguments

【问题讨论】:

***.com/questions/33566075/… 从技术上讲,它是重复的。但是当你有 2 个参数时,你必须使用 typeof(IRepository&lt;,&gt;) 而不是 typeof(IRepository&lt;&gt;) 因为它有两个通用参数 @Tseng 你能否提一下如何启动存储库的构造函数?也许将其添加为答案,我可以将其标记为完成。 启动是什么意思?具体实现的构造函数中的任何参数(即GenericRepository&lt;TIdType,TEntityType&gt;将由IoC容器解析。在需要它的服务中,您可以通过IRepository&lt;int,User&gt;请求它 @Tseng 请完成完整的问题 【参考方案1】:

由于这个问题仍然没有正确标记为duplicate:注册泛型类的方法:

services.AddScoped(typeof(IRepository<,>), typeof(Repository<,>));

现在您可以通过以下方式解决它:

serviceProvider.GetService(typeof(IRepository<A,B>));
// or: with extensionmethod
serviceProvider.GetService<IRepository<A,B>>();

【讨论】:

感谢您的回答,但为了澄清存储库没有默认构造函数,因为它需要使用连接字符串启动。目前我将依赖项注册为services.AddSingleton&lt;IRepository&lt;int, Department&gt;&gt; ( p=&gt; new Repository&lt;int, Department&gt;(connectionString));,但是在使用services.AddScoped(typeof(IRepository&lt;,&gt;), typeof(Repository&lt;,&gt;));时如何传递连接字符串@ @Vijay 使用 IOptions 模式,这样你可以注入一个类型化的类/选项,字符串不会像你说的那样工作,因为你要在构造函数中手动定义字符串 您的意思是我的存储库将依赖于 MyConnectionStringOptions 类型,这意味着我在 DI 中使用填充了正确连接字符串的实例来注册它。这样存储库的构造函数就可以使用GetService连接字符串选项对象并继续? 没错,我会称它为DatabaseOptions 并添加Timeout 以及其他一些有用的选项,并使用IOptions 模式和ConfigurationBuilder 使其从Appsettings 填充 @Vijay 你的注册是单身怎么办?或者这与你不再相关了?除非这个答案以某种我看不到的方式创建了一个单例......

以上是关于如何添加通用依赖注入[重复]的主要内容,如果未能解决你的问题,请参考以下文章

如何将通用存储库(或业务逻辑层)注入 ViewModel

Java服务器端应用程序的静态依赖注入解决方案?

Gin实现依赖注入

什么是依赖注入? [复制]

Spring 依赖注入原理

依赖注入 gin项目的目录结构说明