Я использую веб-приложение с сервисами Autofac, внедряющими в контроллеры. Эти сервисы иногда внедряются с другими сервисами и репозиториями. Репозитории вводятся с помощью DbContexts. Эти 3 уровня (сервис, репозиторий, контекст) все зарегистрированы в Autofac. Мое время жизни по умолчанию для них - InstancePerLifetimeScope.
К сожалению, у меня есть некоторый код в конкретном контроллере, который я хочу выполнить в параллельных потоках. Поскольку DbContext не является потокобезопасным, это означает, что мне нужно предоставить фабричный метод для каждого потока, чтобы разрешить Сервис в области времени жизни для каждой зависимости, которая, в свою очередь, должна будет разрешать репозитории для зависимостей и контексты БД.
Варианты, которые я рассматриваю, состоят в том, чтобы создать новую область действия времени жизни для каждого потока или использовать отдельную регистрацию, используя именованную или основанную на ключах регистрацию для разрешения служб для зависимости.
Проблема с созданием новой области действия жизнидля каждого потока мне нужен доступ к некоторым объектам для каждой области. Некоторые объекты должны быть унаследованы и не иметь нового экземпляра, созданного в новой области, но другим объектам (не ориентированным на потоки DbContexts) должны быть созданы новые экземпляры в новой области. Я понятия не имею, как неявно управлять этим поведением при создании моей новой области жизни.
Другой метод заключается в использовании регистрационного ключа, чтобы при выполнении фабричного метода для разрешения службы в каждом потоке онразрешил бы один в области для зависимости. Это работало бы, если бы у службы не было зависимостей, но так как это зависит от группы репозиториев или служб, для которых область действия по умолчанию установлена в InstancePerLifetimeScope, я должен написать что-то вроде этого:
builder.RegisterType<MyService>()
.As<IMyService>()
.Named<IMyService>(RegistrationKeys.PerDependency)
.WithParameter(new ResolvedParameter(
(pi, ctx) => pi.ParameterType == typeof(IMyRepository),
(pi, ctx) => ctx.ResolveNamed<IMyRepository>(RegistrationKeys.PerDependency))
).InstancePerDependency();
Так какрепозитории зависят от DbContext, каждый репозиторий должен быть зарегистрирован отдельно, используя это регистрационное имя. И это должно быть настроено для разрешения DbContext, используя регистрационное имя. И DbContext должен быть зарегистрирован, используя регистрационное имя.
С 10 сервисами, каждый из которых использует около 4-5 репозиториев, я держу пари, что количество регистрационного кода, которое мне придется написать, будет составлять около 10-20 полных страниц. ,Он не будет обслуживаемым.
Так что мой вопрос в том, есть ли способ создать определенный тип жизненного диапазона, который позволит мне легко контролировать, какие объекты будут иметь новый экземпляр или которые будут унаследованы отродительская область времени жизни, которая не нарушает область жизни каждого запроса asp.net?
Или есть ли способ зарегистрировать или разрешить службу, чтобы явно разрешить все ее зависимости в том жеscope не полагаясь на их регистрации по умолчанию и без необходимости жестко кодировать весь второй набор регистраций для всего?