2017-09-03 97 views
3

我有一个泛型类和通用接口是这样的:依赖注入的泛型类

public interface IDataService<T> where T: class 
{ 
    IEnumerable<T> GetAll(); 
} 

public class DataService<T> : IDataService<T> where T : class 
{ 
    public IEnumerable<T> GetAll() 
    { 
     return Seed<T>.Initialize(); 
    } 
} 

public static IEnumerable<T> Initialize() 
{ 
    List<T> allCalls = new List<T>(); 
    .... 
    return allCalls; 
} 
在我StartUp.cs我挂钩的类和接口

现在

public void ConfigureServices(IServiceCollection services) 
{ 
    services.AddTransient(typeof(IDataService<>), typeof(DataService<>)); 
    ... 
} 

当我尝试在我的例子中使用它Repository.cs始终为空。

public class Repository<T> : IRepository<T> where T : class 
{ 
    private readonly IDataService<T> _dataService; 

    public Repository(IDataService<T> dataService) 
    { 
     _dataService = dataService; 
    ... 
    } 
    ... 
} 

编辑 这里是要求仓库接口和类

public interface IRepository<T> where T : class 
{ 
    double GetCallPrice(T callEntity, Enum billingType); 
    double GetCallPriceFromIdAndBillingType(int id, Enum billingType); 
} 

而且Repository.cs类

public class Repository<T> : IRepository<T> where T : class 
{ 
    private readonly IDataService<T> _dataService; 
    private IEnumerable<T> _allCalls; 

    public Repository(IDataService<T> dataService) 
    { 
     _dataService = dataService; 
    } 

    public double GetCallPrice(int id) 
    { 
     _allCalls = _dataService.GetAllCalls(); 
     ... 
    } 
    ... 
} 
+1

你正在做的事情错了,你是不是在你的问题显示。此外,据我所知,内建的ASP.NET Core DI容器不允许向构造函数中注入“null”值。请说明你如何注册和解决'Repository ',或者更确切地说:请创建一个[最小,完整和可验证的示例](https://stackoverflow.com/help/mcve)。 – Steven

回答

2
services.AddTransient(typeof(IDataService<>), typeof(DataService<>)); 

理想这不应该被允许,但方法接受类型作为参数,它不需要执行任何验证。正如没有人期望任何人会尝试使用它。

的原因,它是空的,因为typeof(IDataService<>) !== typeof(IDataService<SomeClass>)

您可以在https://dotnetfiddle.net/8g9Bx7

就是这个道理检查例子,DI解析器将永远不知道如何解决。大多数DI容器只有在类型实现了请求的接口或者具有基类作为请求的类时才解析类型。

任何DI容器将解决A型B型,仅当A继承了B或A实现B.

在你的情况,DataService<>实现IDataService<>,但DataService<T>没有实现IDataService<>

只有这样,你可以把它的工作是通过调用同为每个数据类型

services.AddTransient(typeof(IDataService<Customer>), typeof(DataService<Customer>)); 

services.AddTransient(typeof(IDataService<Order>), typeof(DataService<Order>)); 

services.AddTransient(typeof(IDataService<Message>), typeof(DataService<Message>)); 

OR

您可以创建一个服务工厂...

interface IDataServiceFactory{ 
    DataService<T> Get<T>(); 
} 

class DataServiceFactory : IDataServiceFactory{ 
    public DataService<T> Get<T>(){ 
      //.. your own logic of creating DataService 

      return new DataService<T>(); 
    } 
} 

和注册

services.AddTransient(typeof(IDataServiceFactory), typeof(DataServiceFactory)); 
+0

感谢您的回答,但我不确定如何使用它。我该做什么才能使它工作? – Ovis

+0

我已经更新了答案,您必须手动添加每个类型。 –

+0

我无法得到您的第一个解决方案,第二个我没有得到 – Ovis