我有一个奇怪的情况。我像这样
在启动类中注册我的服务public void ConfigureServices(IServiceCollection services)
{
...
services.AddSingleton<ISearchService, SearchService>();
services.AddSingleton<IBrandSearchService, BrandSearchService>();
services.AddSingleton<INearbySearchService, NearbySearchService>();
services.AddSingleton<ILocationService, LocationService>();
...
}
但是当我尝试在控制器的构造函数中访问它们时,它们为null,即使我将其添加到构造函数参数中,或尝试从ServiceCollection获取
public class SuggestController
{
readonly ILocationService locationService;
public SuggestController(IOptions<SiteSettings> settings, IOptions<DBAccessBuilder> access, IStringLocalizer<SharedResources> localizer, IMemoryCache memoryCache, IHostingEnvironment environment)
{
this.locationService = (ILocationService)new ServiceCollection().BuildServiceProvider().GetService(typeof(ILocationService));
}
}
实现ILocationService接口的我的Location类
public class LocationService : ILocationService
{
readonly ISolrOperations<LocationResult> search;
...
public LocationService(ISolrOperations<LocationResult> search)
{
this.search = search;
}
...
}
我想念什么?
答案 0 :(得分:0)
您没有注入服务。相反,您尝试使用服务定位器反模式来获取它,但实际上并没有使用真正的服务集合。您正在创建一个新的服务集合,而没有为所需的服务注册,然后尝试从中退出服务,这当然会失败。
尽管这仍然不是正确的方法,但是要正确地正确使用服务定位符反模式,您需要注入IServiceProvider
:
public SuggestController(IServiceProvider provider, ...)
{
this.locationService = provider.GetRequiredService<ILocationService>();
}
然后,那将只起作用,因为在这种情况下,您的特定服务是单例。如果是作用域,则必须首先创建一个作用域:
using (var scope = provider.CreateScope())
{
var locationService = scope.ServiceProvider.GetRequiredService<ILocationService>();
}
但是,在范围内检索到的所有内容仅在该范围内可用。因此,对于作用域服务,您必须将每个操作都包装在这样的用法中(即,您不能将服务持久化到ivar)。
所有这些,在这里,您正在注入控制器,因此,您可以直接注入依赖项,而不必依赖服务定位器反模式(出于某种原因,这是一个反模式)。因此,您确实要做的只是注入ILocationService
:
public SuggestController(ILocationService locationService, ...)
{
this.locationService = locationService;
}