2017-09-03 116 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