Доступ к состоянию службы Azure Service Fabric с отслеживанием состояния

Я добавил WebAPI в свою серию с отслеживанием состояния и хочу получить доступ к StateManager из него (вне реализации класса StatefulService).

Как лучше всего это сделать?

В настоящее время я использую для этого небольшой класс:

internal static class InstanceAccessor
{
   internal static StatefulService ActiveInstance { get; set; }
}

И поместите значение в метод RunAsync StatefulService:

protected override async Task RunAsync(CancellationToken cancellationToken)
{
    InstanceAccessor.ActiveInstance = this;
    ...

person Andriy Kozachuk    schedule 05.02.2017    source источник


Ответы (2)


На Github, который показывает простой способ сделать это с помощью зависимости инъекция.

person LoekD    schedule 06.02.2017
comment
Ссылки в этом ответе мертвы. - person Fourth; 05.07.2018
comment
просто исправил их. - person LoekD; 06.07.2018

Ваша служба потенциально будет иметь несколько одновременных вызовов, обращающихся к общему экземпляру, в вашем коде возможно (но немного маловероятно), что запрос к WebApi будет выполнен до того, как RunAsync установит экземпляр. Вы можете переместить задание в .ctor службы. Но, поскольку он только читает, вы будете делать это с общим экземпляром, вам не нужно беспокоиться о конфликтах после того, как вы установили экземпляр.

Проблема с этим решением - возможность тестирования. Если вы хотите писать модульные тесты для своего WebAPi, он будет жестко зависеть от общего экземпляра. Подробнее об этом см. В этом ответе: Модульное тестирование с одиночными версиями

Другой способ, который может сработать для вас, - это работа с внедрением зависимостей и контейнером IoC. Вы можете настроить свои контроллеры WebApi так, чтобы они создавались контейнером, который имеет ссылки на все зависимости (включая вашу службу). Настроить IoC и внедрение зависимостей для Service Fabric / WebApi можно, как описано здесь https://stackoverflow.com/a/41980513/1062217. Вам просто нужно добавить зависимость от вашего StatefulService в контроллер .ctor.

 public SomeApiController(StatefulService service)
 {
     _service = service;
 }

И зарегистрируйте услугу в контейнере

public WebApiService(StatefulServiceContext context)
    : base(context)
{
    Container = new TinyIoCContainer();
    Container.Register<StatefulService>(this);
}

Однако, если это всего лишь Statemanager, который вам нужен в контроллере WebApi, вашу реализацию будет легче тестировать и поддерживать, если вы просто возьмете зависимость от StateManager:

 public SomeApiController(IReliableStateManagerReplica stateManager)
 {
     _stateManager = stateManager;
 }

и зарегистрируйте это в сервисе .ctor:

public WebApiService(StatefulServiceContext context)
    : base(context)
{
    Container = new TinyIoCContainer();
    Container.Register<IReliableStateManagerReplica>(this.StateManager);
}

обратите внимание, что в этом примере используется TinyIoC, но подойдет любой контейнер IoC

person yoape    schedule 05.02.2017