【问题标题】:Unable to resolve service for type ASP.NET Core DI无法解析 ASP.NET Core DI 类型的服务
【发布时间】:2018-05-29 15:11:06
【问题描述】:

看到一些奇怪的场景,当调用使用它的控制器时,我在 .NET Standard 2.0 CL 服务中遇到 DI 错误。

控制器

[Route("api/[controller]")]
public class VideoController : Controller
{
    private readonly IVideoService _videoService;

    public VideoController(IVideoService videoService)
    {
        _videoService = videoService;
    }
    [HttpGet("[action]")]
    public List<Video> GetVideos()
    {
        return _videoService.GetVideos().Result.ToList();
    }
}

CL 中的服务

public class VideoService : IVideoService
{
    private readonly ILogger log;
    private readonly ConfigWrapper config;

    private readonly IAzureMediaServicesHelpers amsHelpers;
    private readonly IStorageHelpers storageHelpers;

    public VideoService(ILogger logger, ConfigWrapper _config, IAzureMediaServicesHelpers _amsHelper, IStorageHelpers _storageHelper)
    {
        log = logger;
        config = _config;
        amsHelpers = _amsHelper;
        storageHelpers = _storageHelper;
    }

在 .NET Core 项目中启动

public void ConfigureServices(IServiceCollection services)
{
    services.AddTransient<IStorageHelpers, StorageHelpers>();
    services.AddTransient<IAzureMediaServicesHelpers, AzureMediaServicesHelpers>();
    services.AddTransient<IVideoService, VideoService>();
    services.AddMvc();
}

我得到的错误是典型的中间件异常

在尝试激活 Demo.Shared.VideoService' 时无法解析类型“Microsoft.Extensions.Logging.ILogger”的服务。

我这里没有使用 Logger,因为这个 CL 也被不支持 Logger 的 Azure Function 使用。我想我错过了一些简单的东西。

【问题讨论】:

  • 您仍然需要告诉 DI 框架如何处理 ILogger。一个简单但笨拙的解决方案是创建一个 ILogger 的虚拟实现并使用它。
  • 那会是什么样子?
  • 这是你的代码,只有你能说出ILogger 的样子。
  • 所以如果 ILogger(写我自己的 log.Error 等)我创建一个副本?我不能在某处注册 ILogger 的实例吗?
  • 假设这是标准的 ASP.NET MVC Core ILogger,那么应该已经有一个可供您使用...docs.microsoft.com/en-us/aspnet/core/fundamentals/logging/…

标签: .net dependency-injection .net-core .net-standard


【解决方案1】:

按预期工作。创建一个与“什么都不做”的 ILogger 匹配的类并注册它。有一天,您可能想用一种真正的日志记录方法替换那个假人。

From the DLL: Microsoft.Extensions.Logging


Class MyLovelyClass
    Implements Microsoft.Extensions.Logging.ILogger

    Public Sub Log(Of TState)(logLevel As LogLevel, eventId As EventId, state As TState, exception As Exception, formatter As Func(Of TState, Exception, String)) Implements ILogger.Log
        Throw New NotImplementedException()
    End Sub

    Public Function IsEnabled(logLevel As LogLevel) As Boolean Implements ILogger.IsEnabled
        Throw New NotImplementedException()
    End Function

    Public Function BeginScope(Of TState)(state As TState) As IDisposable Implements ILogger.BeginScope
        Throw New NotImplementedException()
    End Function
End Class

【讨论】:

  • 这是如何工作的?我实际上想记录一些东西。如果我有一个虚拟类,它不会做任何事情。
  • 看来您已经解决了自己的问题。直接跳到制作一个兼容的记录器,然后记录:)
  • 我的困惑是我在 ASP.NET Core 中使用 DefaultBuilder。所以这一切都应该为我完成。 github.com/aspnet/MetaPackages/blob/dev/src/…
  • DI 只知道您在其中注册的内容。没有魔法。执行其中一种解决方案,或者不执行。
  • 但是 DefaultBuilder 也注册了它。如果我不 DI 服务,控制器工作正常,记录器工作。
【解决方案2】:

只需使用ILogger&lt;VideoService&gt; 而不是 ILogger。尝试像这样更改 VideoService 构造函数:

public VideoService(ILogger<VideoService> logger, ConfigWrapper _config, IAzureMediaServicesHelpers _amsHelper, IStorageHelpers _storageHelper)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-01-29
    • 2022-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多