Внедрить с другой областью действия при использовании DbContext с пользовательским поставщиком ресурсов
В приложении у меня есть следующие компоненты (среди прочих):
MyDbContext
: Доступ к данным Entity FrameworkDBResourceProviderFactory
: ОбычайResourceProviderFactory
предоставление пользовательскихIResourceProvider
(называетсяDBResourceProvider
...)- Другие услуги
- StructureMap
Пользовательский поставщик ресурсов ищет ресурсы в БД, используя MyDbContext
вводится так же, как описано в этом SO ответе.
MyDbContext
также используется в различных других службах, и поскольку это веб-приложение, я использую StructureMaps HttpContextScoped
способ ограничить время жизни MyDbContext
к времени существования запроса (см. другой вопрос SO и его ответ на эту тему):
x.For<MyDbContext>().HttpContextScoped();
Тем не менее, кажется, что время жизни IResourceProvider
не ограничивается одним запросом http. Следовательно, DBResourceProvider
продолжает висеть на MyDbContext
ссылка, которая будет удалена после первого запроса.
Как я могу справиться с этим несоответствием времени жизни - чтобы StructureMap возвращал переходный процесс MyDbContext
за IDbResourceProvider
при возврате экземпляров в области HttpContext во все остальные службы?
Нужны ли мне две разные реализации для этого? Интерфейс маркера? Или это плохая идея использовать Entity Framework для поиска локализованных ресурсов в первую очередь (производительность и т. Д.)?
1 ответ
Если у вас есть служба, которая имеет (или должна иметь) более длительный срок службы, чем (одна из) ее зависимостей, общее решение заключается в использовании фабрики для получения этих зависимостей.
В вашей ситуации решение может быть простым. Когда ваш DBResourceProvider
определяется в корне вашей композиции вашего приложения MVC, было бы просто успешно использовать DependencyResolver.Current.GetService
способ получить MyDbContext
,
Когда DBResourceProvider
служба не является частью корня композиции (например, потому что она содержит бизнес-логику, которую нужно протестировать), вы можете либо извлечь эту логику в свой собственный класс, чтобы позволить службе находиться в корне композиции, либо вы можете внедрить (синглтон) фабрика (например, IDbContextFactory
или же Func<MyDbContext>
), который позволяет вам получить правильный экземпляр, который будет решен.