Я не внедряю сервис в контроллер - PullRequest
0 голосов
/ 30 января 2019

У меня странная ситуация.Я регистрирую свои сервисы в классе запуска, например,

public void ConfigureServices(IServiceCollection services)
{
    ...
    services.AddSingleton<ISearchService, SearchService>();
    services.AddSingleton<IBrandSearchService, BrandSearchService>();
    services.AddSingleton<INearbySearchService, NearbySearchService>();
    services.AddSingleton<ILocationService, LocationService>();
    ...
}

, но когда я пытаюсь получить к ним доступ в конструкторе контроллера, они становятся нулевыми, даже если я добавляю их в параметры конструктора или пытаюсьполучить из 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));
    }
}

Класс My Location, который реализует интерфейс ILocationService

public class LocationService : ILocationService
{
    readonly ISolrOperations<LocationResult> search;

    ...

    public LocationService(ISolrOperations<LocationResult> search)
    {
        this.search = search;
    }

    ...
}

Чего мне не хватает?

1 Ответ

0 голосов
/ 30 января 2019

Вы не вводите свой сервис.Вместо этого вы пытаетесь использовать антипаттерн сервисного локатора, чтобы получить его, но на самом деле вы не используете свой реальный набор сервисов.Вы создаете новую коллекцию сервисов без регистрации для нужной вам службы и пытаетесь извлечь из нее свою службу, что, конечно, не помогает.

Хотя это, во всяком случае, неправильный метод, фактическиПравильно используйте антипаттерн локатора службы, вам нужно будет ввести 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;
}
...