C# 使用http作用域实例的StructureMap Web Api和依赖项注入

C# 使用http作用域实例的StructureMap Web Api和依赖项注入,c#,dependency-injection,asp.net-web-api,ravendb,structuremap,C#,Dependency Injection,Asp.net Web Api,Ravendb,Structuremap,正如标题所说,我正在尝试使用StructureMap、Web Api和RavenDB会话的HybridHttpOrthReadLocalScope实例使用依赖项注入 为此,我使用的是IHTTPC控制器激活器,请参见下面的代码 public class StructureMapControllerActivator : IHttpControllerActivator { private readonly IContainer _container; public Structu

正如标题所说,我正在尝试使用StructureMap、Web Api和RavenDB会话的
HybridHttpOrthReadLocalScope
实例使用依赖项注入

为此,我使用的是
IHTTPC控制器激活器
,请参见下面的代码

public class StructureMapControllerActivator : IHttpControllerActivator
{
    private readonly IContainer _container;

    public StructureMapControllerActivator(IContainer container)
    {
        if (container == null) throw new ArgumentNullException("container");
        _container = container;
    }

    public IHttpController Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)
    {
        try
        {
            var scopedContainer = _container.GetNestedContainer();
            scopedContainer.Inject(typeof(HttpRequestMessage), request);
            request.RegisterForDispose(scopedContainer);
            return (IHttpController)scopedContainer.GetInstance(controllerType);
        }
        catch (Exception e)
        {
            // TODO : Logging
            throw e;
        }
    }
}
在my global.asax中,我将
IHTTP控制器激活器连接如下:

GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpControllerActivator), new StructureMapControllerActivator(ApplicationContainer));
public MyApiController(IDocumentSession session) {
    _session = session;
}
这是我对StructureMap的配置:

expression.For<IDocumentStore>().Use(documentStore);
expression.For<IDocumentSession>()
    .HybridHttpOrThreadLocalScoped()
    .Use(container =>
    {
        var store = container.GetInstance<IDocumentStore>();                        
        return store.OpenSession();
    });
当我发出第一个
请求时,我得到了
文档会话的一个实例,但是第二个
请求在这一行
return store.OpenSession()
上抛出一个
HttpError
异常。异常状态表示该对象已被释放,无法使用。这是一个完全例外:

{
  "$type": "System.Web.Http.HttpError, System.Web.Http",
  "message": "An error has occurred.",
  "exceptionMessage": "StructureMap Exception Code:  207\nInternal exception while creating Instance '6d9a72a3-3044-495a-909c-dd9fe7527c80' of PluginType Raven.Client.IDocumentSession, Raven.Client.Lightweight, Version=2.5.0.0, Culture=neutral, PublicKeyToken=37f41c7f99471593.  Check the inner exception for more details.",
  "exceptionType": "StructureMap.StructureMapException",
  "stackTrace": "   at BrickPile.Mvc.StructureMapControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType) in c:\\Users\\maqe\\Documents\\Visual Studio 2013\\Projects\\brickpile\\BrickPile\\Mvc\\StructureMapWebApiDependencyResolver.cs:line 61\r\n   at System.Web.Http.Controllers.HttpControllerDescriptor.CreateController(HttpRequestMessage request)\r\n   at System.Web.Http.Dispatcher.HttpControllerDispatcher.SendAsyncCore(HttpRequestMessage request, CancellationToken cancellationToken)\r\n   at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__0.MoveNext()",
  "innerException": {
    "$type": "System.Web.Http.HttpError, System.Web.Http",
    "message": "An error has occurred.",
    "exceptionMessage": "The document store has already been disposed and cannot be used\r\nObject name: 'EmbeddableDocumentStore'.",
    "exceptionType": "System.ObjectDisposedException",
    "stackTrace": "   at Raven.Client.Document.DocumentStore.OpenSession(OpenSessionOptions options) in c:\\Builds\\RavenDB-Stable\\Raven.Client.Lightweight\\Document\\DocumentStore.cs:line 355\r\n   at BrickPile.DefaultBrickPileBootstrapper.<>c__DisplayClassc.<ConfigureApplicationContainerInternal>b__a(IContext container) in c:\\Users\\maqe\\Documents\\Visual Studio 2013\\Projects\\brickpile\\BrickPile\\DefaultBrickPileBootstrapper.cs:line 294\r\n   at StructureMap.Pipeline.LambdaInstance`1.build(Type pluginType, BuildSession session) in c:\\BuildAgent\\work\\767273992e840853\\src\\StructureMap\\Pipeline\\LambdaInstance.cs:line 25"
  }
}
{
“$type”:“System.Web.Http.HttpError,System.Web.Http”,
“消息”:“发生错误。”,
“exceptionMessage:“StructureMap异常代码:207\n创建插件类型Raven.Client.IDocumentSession、Raven.Client.Lightweight、Version=2.5.0.0、Culture=neutral、PublicKeyToken=37f41c7f99471593的实例“6d9a72a3-3044-495a-909c-dd9fe7527c80”时出现内部异常。有关详细信息,请检查内部异常。”,
“exceptionType”:“StructureMap.StructureMappException”,
“stackTrace”:“at brickfile.Mvc.StructureMapControllerActivator.Create(HttpRequestMessage请求、HttpControllerDescriptor controllerDescriptor、Type controllerType)在c:\\Users\\maqe\\Documents\\Visual Studio 2013\\Projects\\brickfile\\brickfile\\Mvc\\structuremapWebApidenceResolver.cs中:System.Web.Http.Controllers.HttpControllerDescriptor.CreateController(HttpRequestMessage请求)的第61行\r\n处System.Web.Http.Dispatcher.HttpControllerDispatcher.SendAsyncCore(HttpRequestMessage请求,CancellationToken CancellationToken)\r\n位于System.Web.Http.Dispatcher.HttpControllerDispatcher.d_u0.MoveNext()“,
“内部异常”:{
“$type”:“System.Web.Http.HttpError,System.Web.Http”,
“消息”:“发生错误。”,
“exceptionMessage”:“文档存储已被释放,无法使用\r\n对象名:'EmbeddedBledDocumentStore'。”,
“exceptionType”:“System.ObjectDisposedException”,
c:\\Builds\\RavenDB Stable\\Raven.Client.Lightweight\\Document\\DocumentStore.cs:brickfile.DefaultBrickPileBootstrapper.c\u显示类c.b\u a(IContext容器)中的第355行在c:\\Users\\maqe\\Documents\\Visual Studio 2013\\Projects\\brickfile\\brickfile\\defaultbrickpile bootstrapper.cs:StructureMap.Pipeline.LambdaInstance`1.build(Type pluginType,BuildSession session)中,c:\\BuildAgent\\work\\767273992e840853\\src\\StructureMap\\Pipeline\\LambdaInstance.cs:line 25“
}
}
有人能帮我解决我这里缺少的东西吗


我忘了提到我使用
IHttpModule
来释放和处理
Application\u EndRequest
中的所有http作用域对象。我忘了将
.Singleton()
添加到
expression.for().use(documentStore);
中。上面的代码经过此修改后可以正常工作。

我添加了
.Singleton()
to
expression.For()。使用(documentStore)
现在它似乎与我在问题中发布的代码完全相同。有人能确认解决方案吗?这是正确的。
IDocumentStore
实例应该是一个单例,
IDocumentSession
实例应该是HTTP作用域。默认情况下,StructureMap每次都会创建一个新的类实例。确定要t到
throw e;
?大多数时候,它应该是
throw;
,因为您正在丢失调用堆栈。