如何添加通用依赖注入

Vij*_*jay 9 c# generics dependency-injection .net-core asp.net-core

使用只读api服务并利用泛型将操作打包到基于约定的流程中.

存储库界面:

public interface IRepository<TIdType,TEntityType> where TEntityType:class {
   Task<EntityMetadata<TIdType>> GetMetaAsync();
}
Run Code Online (Sandbox Code Playgroud)

存储库实现:

public class Repository<TIdType,TEntityType> : IRepository<TIdType,TEntityType> where TEntityType:class {
   public Repository(string connectionString) { // initialization }
   public async Tas<EntityMetadata<TIdType>> GetMetaAsync() { // implementation   }
}
Run Code Online (Sandbox Code Playgroud)

Startup.cs -> 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
Run Code Online (Sandbox Code Playgroud)

控制器:

public class EmployeeController : Controller {
   public EmployeeController(IRepository<int,Employee> repo) {//stuff}
}
Run Code Online (Sandbox Code Playgroud)

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

services.AddSingleton<IRepository<TIdType, TEntityType>> ( p=> new Repository<TIdType, TEntityType>(connectionString));
Run Code Online (Sandbox Code Playgroud)

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

更新1:不重复:

  1. 存储库实现没有默认构造函数
  2. 因为它没有默认构造函数,所以我无法提供链接问题中给出的解决方案.
  3. 在尝试时services.AddScoped(typeof(IRepository<>), ...)我得到错误Using the generic type 'IRepostiory<TIdType,TEntityType>' requires 2 type arguments

Joe*_*kes 16

由于此问题仍未正确标记为重复:注册Generic类的方法:

services.AddScoped(typeof(IRepository<,>), typeof(Repository<,>));
Run Code Online (Sandbox Code Playgroud)

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

serviceProvider.GetService(typeof(IRepository<A,B>));
// or: with extensionmethod
serviceProvider.GetService<IRepository<A,B>>();
Run Code Online (Sandbox Code Playgroud)

  • 感谢您的回答,但为了澄清存储库没有默认构造函数,因为它需要使用连接字符串启动。目前我正在将依赖项注册为 `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;));` (3认同)