无法在启动中解析来自接口的通用DI

时间:2019-08-31 11:43:57

标签: c# generics dependency-injection interface

我已经创建了一个通用接口

 public interface ISqlTradeDataRetriever<T> where T : class
{
    Task<T> GetSingleDayForSymbolAsync(string symbol, string date);

    Task<ICollection<T>> GetAllAsync(string symbol);        
}

及其实现

 public class SqlCommodityDataRetriever: ISqlTradeDataRetriever<Commodity>
{
    private readonly BatlGroupWebContext _context;

    public SqlCommodityDataRetriever(BatlGroupWebContext context)
    {
        _context = context;
    }


    public Task<Commodity> GetSingleDayForSymbolAsync(string symbol, string date)
    {
        var data = _context.Commodities.FirstOrDefaultAsync(m => m.Symbol == symbol
                                                                 && m.TradeDate == Convert.ToDateTime(date));

        return data;
    }

    public Task<ICollection<Commodity>> GetAllAsync(string symbol)
    {
        throw new NotImplementedException();
    }
}

和Web应用程序的startup.cs中

 services.AddScoped<ISqlTradeDataRetriever<Commodity>, SqlCommodityDataRetriever>();

但是当我尝试访问使用此实现的页面时,出现未解决的DI错误

  

尝试激活“ BATLGroupApp.Pages.Commodity.TradeData.EditModel”时,无法解析“ Infrastructure.DataRetrievers.SqlCommodityDataRetriever”类型的服务。

编辑模型如下

public class EditModel : PageModel
{
    private readonly SqlCommodityDataRetriever _retriever;

    public EditModel(SqlCommodityDataRetriever retriever)
    {
        _retriever = retriever;
    }

    [BindProperty]
    public DomainClasses.Classes.Commodity Commodity { get; set; }
    public string CommoditySymbol { get; set; }

    public async Task<IActionResult> OnGetAsync([FromQuery]string symbol, [FromQuery]string date)
    {
        if (string.IsNullOrEmpty(symbol) || string.IsNullOrEmpty(date))
        {
            return NotFound();
        }

        Commodity = await _retriever.GetSingleDayForSymbolAsync(symbol, date);
        if (Commodity == null)
        {
            return NotFound();
        }

        CommoditySymbol = Commodity.CommoditySymbol.Symbol;

        return Page();
    }
 }

在为此注册DI方面我做错了什么,或者我的实现错了吗?

1 个答案:

答案 0 :(得分:2)

目前的注册形式还可以。

s1 = (s1 * .30) / 100;

但是,页面模型期望具体的services.AddScoped<ISqlTradeDataRetriever<Commodity>, SqlCommodityDataRetriever>(); 实现,而容器仅知道其SqlCommodityDataRetriever抽象。

重构页面模型以匹配注册

ISqlTradeDataRetriever<Commodity>

因为类在理想情况下应该依赖抽象而不是混凝土,以实现更坚固的设计。