Как настроить контейнер Orleans DI для разрешения службы с одним и тем же экземпляром для графа объекта зерна?

Я использую Microsoft Orleans, и у меня есть зерно под названием ConsumerGrain, которое связано с подпиской Azure по идентификатору подписки. Зерно внедряется с помощью нескольких прикладных сервисов, чтобы соответствовать принципам SOLID. Для некоторых служб приложений требуется идентификатор подписки. Вместо того, чтобы передавать идентификатор подписки при каждом вызове метода, я хотел бы, чтобы объект ISubscriptionContext внедрялся в каждую службу приложений, для которой требуется текущий идентификатор подписки, и я хотел бы, чтобы экземпляр службы создавался один раз для каждого графа объекта зерна, так что это не может быть образ жизни Transient, а не Singleton. Можно ли здесь использовать Scoped lifestyle?


person Eldar    schedule 15.03.2016    source источник
comment
Интересный вопрос. Я не видел каких-либо крупных пакетов интеграции IoC libs для Orleans. Как правило, контейнеры IoC имеют два способа решения такого случая: вручную BeginLifetimeScope, как в Autofac, или связывание области с объектом в графе, например LifeStyle.BoundTo в Castle.Winsdor, PerOwned в Autofac.   -  person dadhi    schedule 15.03.2016
comment
В Unity DI есть что-то вроде менеджера времени жизни для каждого решения. Поскольку Orleans использует ASP.NET Core DI, который представляет собой так называемую соответствующий контейнер такого типа разрешения зависимостей не существует. Одним из решений может быть открытие области для каждого экземпляра зерна и регистрация зависимостей как синглетонов с областью действия. Но эта область должна открываться инфраструктурой Орлеана всякий раз, когда создается экземпляр зерна. Как следствие, область должна быть закрыта, когда зерно дезактивировано.   -  person Peter Perot    schedule 18.10.2016


Ответы (2)


Orleans использует IServiceProvider, возвращаемый классом Silo Startup, только для разрешения зерна. Это означает, что приложение может возвращать составной IServiceProvider со следующей логикой в ​​классе Startup:

  1. Создайте IServiceProvider на основе IServiceCollection, предоставленного Орлеаном, используемого для решения внутренних проблем Орлеана.
  2. Создайте IServiceProvider для зерен и сервисов приложения, скажем, используя SimpleInjector с образом жизни для каждого объекта-графа.
  3. Возвращает IServiceProvider, который сначала пытается решить с помощью IServiceProvider на основе Орлеана, а если не удается разрешить с помощью приложения на основе IServiceProvider.

класс Startup просто должен иметь метод, соответствующий этой сигнатуре:

public IServiceProvider ConfigureServices(IServiceCollection services)
{
     return services.BuildServiceProvider();
}

этот фрагмент BuildServiceProvider() предоставлен Microsoft.Extensions.DependencyInjection

person Eldar    schedule 16.03.2016

Более подробное объяснение есть по адресу:

http://www.codeproject.com/Articles/1099750/How-to-implement-DI-support-in-your-Orleans-Silo

Важно знать, что вы должны установить класс запуска в файле конфигурации orleans.

<?xml version="1.0" encoding="utf-8"?>
<OrleansConfiguration xmlns="urn:orleans">
  <Globals>
    <SeedNode Address="localhost" Port="10000" />
  </Globals>
  <Defaults>
    <Startup Type="Grains.Startup, Grains" /><!--important-->
    <Networking Address="localhost" Port="10000" />
    <ProxyingGateway Address="localhost" Port="30000" />
  </Defaults>
</OrleansConfiguration> 
person Flo    schedule 17.10.2016