Я использую Castle Windsor для контейнера DI для Web API 2, а некоторые из моих контроллеров имеют зависимости EF DbContext, которые я впрыскиваю, используя следующие установщики CW (это часть работает отлично):Замок Windsor Lifestyle для EF DbContext, необходимый для ведения журнала после запроса веб-API
public class ApiControllerInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(Classes.FromThisAssembly().BasedOn<ApiController>().LifestylePerWebRequest());
}
}
public class MyEntitiesInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(Component.For<MyEntities>().LifestylePerWebRequest());
}
}
у меня также есть глобальное протоколирование на месте с помощью следующего обработчика сообщений:
public class LoggingHandler : DelegatingHandler
{
private readonly IWindsorContainer _container;
public LoggingHandler(IWindsorContainer container)
{
_container = container;
}
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
CancellationToken cancellationToken)
{
// Logic here to parse the request, send off the request, and then parse the response for logging info
// Log to database
using (MyEntities myEntities = _container.Resolve<MyEntities>())
{
// Log to database using MyEntities (DbContext)
}
return response;
}
}
... который получает набор в WebApiConfig.cs, как это:
public static void Register(HttpConfiguration config, IWindsorContainer container)
{
// Unrelated code
config.MessageHandlers.Add(new LoggingHandler(container));
}
Проблема заключается в том, что я получаю исключение в LoggingHandler
при попытке доступа к MyEntities
(который расширяет EF DbContext
), поскольку он говорит, что он уже был удален. Я думаю, что это происходит потому, что MyEntitiesInstaller
регистрирует его как LifestylePerWebRequest()
, и к этому моменту запрос уже завершен. Я не думаю, что это хорошая идея в глобальном изменении образа жизни DbContext
, потому что для целей контроллера api мы хотим, чтобы он был экземпляром для каждого веб-запроса. Но как я могу предотвратить его удаление до начала регистрации (или, что еще лучше, использовать отдельный экземпляр для ведения журнала)?
Я никогда не использовал Castle Windsor, но разве он не поддерживает «названные» конфигурации вещей? Моим инстинктом было бы создать альтернативную именованную конфигурацию для DbContext, а затем настроить свой атрибут для ее использования. – Casey
Я не уверен, что регистрация «MyEntities» - это умная идея. Они должны быть недолговечными в течение всего срока службы запроса, а не всего веб-запроса. Я бы сохранил это просто и просто использовал 'using (var entityContext = new MyEntities())' вместо этого. Нет необходимости в [* «Ввести все вещи» *] (http://s.quickmeme.com/img/fe/fe05577986250c85a9df4c46dbf46afb33332155da3e0f590cfd99bf5259b1dd.jpg). –
@emodendroket Спасибо! Похоже, что именованные экземпляры - это то, что мне нужно - я новичок в контейнерах DI и не знал об этой функции. Я попытаюсь посмотреть, будет ли работать отдельный именованный экземпляр. – mayabelle