我已经阅读了关于同一主题的许多其他SO问题,但是我发现的答案都不适用于我的情况,所以去了:
我已经在Startup.cs中成功添加了4个服务,并且之前运行良好。然后我添加了第5个,现在我意识到有些问题了-所有服务都不起作用。即使我完全删除了第五个,其他两个现在也被破坏了,并且出现了相同的错误。
尝试激活时无法解析xx类型的服务
这是我的Startup.cs ConfigureServices.cs:
public void ConfigureServices(IServiceCollection services)
{
services.AddStorage();
services.AddSingleton<IMyLocalStorage, MyLocalStorage>();
services.AddSingleton<IFrontEndService, FrontEndService>();
services.AddSingleton<ISystemProvider, SystemProviderService>();
services.AddSingleton<IAuthenticationService, AuthenticationService>();
}
它是我注意到该错误的最后一个AuthenticationService,但是现在即使是以前运行的旧服务也失败了。
public interface IAuthenticationService
{
// ...
}
public class AuthenticationService : IAuthenticationService
{
private readonly FrontEndService frontEndService;
private readonly MyLocalStorage myLocalStorage;
public AuthenticationService(FrontEndService frontEndService, MyLocalStorage myLocalStorage)
{
this.frontEndService = frontEndService;
this.myLocalStorage = myLocalStorage;
}
// ...
}
服务很简单;一个接口,该接口的一种实现,然后添加Startup.cs。我不知道为什么它停止工作。
因此,如果我删除IAuthenticationService,则会在FrontEndService中显示错误,然后在MyLocalStorage上进行抱怨:
public interface IFrontEndService
{
Task<T> GetAsync<T>(string requestUri);
}
public class FrontEndService : IFrontEndService
{
private readonly HttpClient client;
private readonly MyLocalStorage myLocalStorage;
public FrontEndService(HttpClient client, MyLocalStorage myLocalStorage)
{
// ...
}
}
和
public class MyLocalStorage : IMyLocalStorage
{
public MyLocalStorage(LocalStorage storage)
{
this.storage = storage;
}
}
我在这里想念什么?
答案 0 :(得分:2)
在IServiceCollection
上调用诸如.AddSingleton<IFrontEndService, FrontEndService>()
之类的方法时,您对容器说:“每当看到IFrontEndService
依赖项时,就插入FrontEndService
的实例”。现在,请看一下您的AuthenticationService
:
public class AuthenticationService : IAuthenticationService
{
private readonly FrontEndService frontEndService;
private readonly MyLocalStorage myLocalStorage;
public AuthenticationService(FrontEndService frontEndService, MyLocalStorage myLocalStorage)
{
this.frontEndService = frontEndService;
this.myLocalStorage = myLocalStorage;
}
// ...
}
请注意如何传递FrontEndService
和MyLocalStorage
的依赖项,而不是您注册的接口。这意味着容器无法识别它们,因此它不知道如何实现依赖关系图。
您需要更改服务以依赖于接口,因为这些是您在容器中注册的:
public class AuthenticationService : IAuthenticationService
{
private readonly IFrontEndService frontEndService;
private readonly IMyLocalStorage myLocalStorage;
public AuthenticationService(IFrontEndService frontEndService, IMyLocalStorage myLocalStorage)
{
this.frontEndService = frontEndService;
this.myLocalStorage = myLocalStorage;
}
// ...
}
答案 1 :(得分:1)
@Ted, 您还记得几周前在服务中使用LocalStorage的问题吗?在该服务处,您有一个带有IStorage参数的构造函数,但这会导致错误,原因是尽管LocalStorage类实现了IStorage接口,但此库的创建者将LocalStorage作为像这样的具体类添加到了DI容器中:
public static IServiceCollection AddStorage(this IServiceCollection services)
{
return services.AddSingleton<SessionStorage>()
.AddSingleton<LocalStorage>();
}
因此,您必须使用
(本地存储存储)
代替
(IStorage存储)
上面的扩展方法可以这样重写:
public static IServiceCollection AddStorage(this IServiceCollection services)
{
return services.AddSingleton<IStorage, SessionStorage>()
.AddSingleton<IStorage, LocalStorage>();
}
在这种情况下,您可以在构造函数中使用IStorage接口。
现在您可以形成一般规则,并采取相应的行动。
Ted说:
那很奇怪,因为我之前完全使用过这种方法,而且 工作正常。如果您阅读文档,Microsoft也会使用具体的 类,而不是接口
HttpClient派生自HttpMessageInvoker。它没有实现任何接口。
此代码段显示了如何将HttpClient添加到服务容器中,以及如何将其注入到您的客户端Blazor中:
services.AddSingleton<HttpClient>(s =>
{
// Creating the URI helper needs to wait until the JS Runtime is initialized, so defer it.
var uriHelper = s.GetRequiredService<IUriHelper>();
return new HttpClient
{
BaseAddress = new Uri(WebAssemblyUriHelper.Instance.GetBaseUri())
};
});
希望这对您有帮助...