注册通用类的依赖注入

时间:2018-09-05 14:34:10

标签: c# asp.net-core

这是我的应用程序结构:

  • 应用
    • 存储库
  • 网站
    • 服务

我有这样的存储库代码

public interface IRepository<T> { }

public class Repository <T> { }

public interface ITestRepository : IRepository<Model> { }

public class TestRepository : Repository<Model>, ITestRepository { }

public interface ITest2Repository : IRepository<Model2> { }

public class Test2Repository : Repository<Model2>, ITest2Repository { }

我正在像这样在Web中使用此存储库来提供服务:

public class TestService : ITestService
{
     private readonly ITestRepository testRepository;
     private readonly ITest2Repository test2Repository;

     public TestService(ITestRepository testRepository, ITest2Repository test2Repository)
     {
         this.testRepository = testRepository;
         this.test2Repository = test2Repository;
     }
}

现在,我正在像这样在Startup.cs中注册存储库。

services.AddScoped(typeof(IRepository<Model>), typeof(TestRepository));
services.AddScoped(typeof(IRepository<Model2>), typeof(Test2Repository));
services.AddScoped<ITestRepository, TestRepository>();
services.AddScoped<ITest2Repository, Test2Repository>();

,我想简化一下。我最近在Google上搜索了注册通用类的方法,但它破坏了我的Program.cs

这是错误:

  

System.ArgumentException:'无法实例化服务类型'Application.Repositories.Interfaces.IRepository1 [TEntity]'的实现类型'Application.Repositories.Repository1 [TEntity]'。

这是我注册存储库的方式:

services.AddScoped(typeof(IRepository<>), typeof(Repository<>));
services.AddScoped<ITestRepository, TestRepository>();
services.AddScoped<ITest2Repository, Test2Repository>();

TL; DR,有什么解决方案可以简化我对该存储库的注册?

1 个答案:

答案 0 :(得分:1)

您可以添加自己的扩展方法以简化注册:

static class ServiceCollectionExtensions
{
    public static void AddRepository<TInterface, TRepository, TModel>(this IServiceCollection serviceCollection) 
        where TInterface : IRepository<TModel> 
        where TRepository : TInterface
    {
        services.AddScoped<TInterface, TRepository>();
        services.AddScoped<IRepository<TModel>, TRepository>();
    }
}

// usage:
services.AddRepository<ITestRepository, TestRepository, Model>();

对于您提到的错误,请参见柯克的评论:

  

看来Repository<T>并没有真正实现IRepository<T>-我明白了为什么DI系统对此不满意。