[英]Make .NET Core DI auto resolve class by generic interface / abstract class implementation
[英].Net Core DI injection Abstract class using Interface in a derived class
我有一個從抽象類派生的派生類,抽象類實現了接口。 我想注入抽象類以使用抽象類和接口類的成員。 我的課看起來像:
public interface IStorageTableQueryHelper
{
IStorageTableQueryHelper Connect(string storageconnectionString, string entityName);
Task<ContinuationTokenPageResult<T>> ExecuteTableQueryAsyncStruct<T>(Expression<Func<TableEntity, bool>> expression,
List<string> selectField) where T : struct;
Task<ContinuationTokenPageResult<T>> ExecuteTableQueryAsyncStruct<T>(string query, List<string> selectField) where T : struct;
}
我的抽象類
public abstract class StorageTableQueryAbstractHelper : IStorageTableQueryHelper
{
public abstract IStorageTableQueryHelper Connect(string storageconnectionString, string entityName);
public abstract Task<ContinuationTokenPageResult<T>> ExecuteTableQueryAsyncStruct<T>(
Expression<Func<TableEntity, bool>> expression, List<string> selectField) where T : struct;
public abstract Task<ContinuationTokenPageResult<T>> ExecuteTableQueryAsyncClass<T>(Expression<Func<TableEntity, bool>> expression, List<string> selectField) where T : class, new();
public abstract Task<ContinuationTokenPageResult<T>> ExecuteTableQueryAsyncStruct<T>(string query,
List<string> selectField) where T : struct;
public abstract Task<ContinuationTokenPageResult<T>> ExecuteTableQueryAsyncClass<T>(string query,
List<string> selectField) where T : class, new();
}
我的派生類
public class StorageTableQueryHelper : StorageTableQueryAbstractHelper
{
private readonly ITableService _tableService;
private string connectionString { get; set; }
private string entityName { get; set; }
public StorageTableQueryHelper(ITableService tableService)
{
_tableService = tableService;
}
public override IStorageTableQueryHelper Connect(string storageConnectionString, string entityTableName)
{
this.connectionString = storageConnectionString;
this.entityName = entityTableName;
return this;
}
public override async Task<ContinuationTokenPageResult<T>> ExecuteTableQueryAsyncStruct<T>(Expression<Func<TableEntity, bool>> expression, List<string> selectField) where T : struct
{
//var result= await _tableService.Connect(this.connectionString,this.entityName).ExecuteQuery<T>(expression, selectField);
return null;
}
public override async Task<ContinuationTokenPageResult<T>> ExecuteTableQueryAsyncClass<T>(Expression<Func<TableEntity, bool>> expression, List<string> selectField) where T : class
{
// var result = await _tableService.Connect(this.connectionString, this.entityName).ExecuteQuery<T>(expression, selectField);
return null;
}
public override async Task<ContinuationTokenPageResult<T>> ExecuteTableQueryAsyncStruct<T>(string query, List<string> selectField) where T:struct
{
//var result = await _tableService.Connect(this.connectionString, this.entityName).ExecuteQuery<T>(query, selectField);
return null;
}
public override async Task<ContinuationTokenPageResult<T>> ExecuteTableQueryAsyncClass<T>(string query, List<string> selectField) where T : class
{
// var result = await _tableService.Connect(this.connectionString, this.entityName).ExecuteQuery<T>(query, selectField);
return null;
}
}
以及我想注入基類以使用接口實現的類
public class EShopBusinessLogicProcessor : IEShopBusinessLogicProcessor
{
private readonly IStorageTableQueryHelper _storageTableQueryHelper;
private EShopHttpRequestPayload _eShopHttpRequestPayload;
public EShopBusinessLogicProcessor(IStorageTableQueryHelper storageTableQueryHelper)
{
_storageTableQueryHelper = storageTableQueryHelper;
}
}
我正在嘗試使用看起來像的 .Net Core DI
services.AddScoped<IStorageTableQueryHelper, StorageTableQueryAbstractHelper>();
services.AddScoped<StorageTableQueryHelper>();
但我無法注入它,因為它說接口不包含定義,即使我嘗試使用抽象類注入
public class EShopBusinessLogicProcessor : IEShopBusinessLogicProcessor
{
private readonly StorageTableQueryAbstractHelper _storageTableQueryHelper;
private EShopHttpRequestPayload _eShopHttpRequestPayload;
public EShopBusinessLogicProcessor(StorageTableQueryAbstractHelper storageTableQueryHelper)
{
_storageTableQueryHelper = storageTableQueryHelper;
}
}
我怎樣才能實現將抽象類注入消費者類?
您可以使用回調注冊接口並解析其中的抽象類。 但是您必須首先將抽象類映射到實現。
// map the abstract class to an implementation
services.AddScoped<StorageTableQueryAbstractHelper, StorageTableQueryHelper>();
// then map the interface to abstract class
services.AddScoped<IStorageTableQueryHelper>(sp => sp.GetRequiredService<StorageTableQueryAbstractHelper>());
// or register it directly with the implementation
// services.AddScoped<IStorageTableQueryHelper, StorageTableQueryHelper>();
您需要將具體類注冊為IStorageTableQueryHelper
實現,而不是抽象類。
services.AddScoped<IStorageTableQueryHelper, StorageTableQueryHelper>();
DI 容器只會解析您已注冊的類型。 它不會嘗試查找已注冊類型之一是從另一個類型繼承還是實現了接口。 如果有 2 或 3 個類實現該接口會怎樣?
這就是為什么你不能只注冊一個具體的類型並注入它實現的接口。
抽象類根本沒有注冊,所以無法解析。 以下構造函數將始終失敗:
public EShopBusinessLogicProcessor(StorageTableQueryAbstractHelper)
要完成這項工作,需要進行以下注冊:
services.AddScoped<StorageTableQueryAbstractHelper, StorageTableQueryHelper>();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.