Asp.net web api 使用SimpleInjector有没有一种方法可以复制RegisterWebapireRequest<;T>;()使用.NET4/webapi 1?

Asp.net web api 使用SimpleInjector有没有一种方法可以复制RegisterWebapireRequest<;T>;()使用.NET4/webapi 1?,asp.net-web-api,simple-injector,Asp.net Web Api,Simple Injector,跟进此事。我正在学习使用SimpleInjector和WebAPI的示例。不幸的是,我想利用WebAPI并阻止我升级到.NET4.5。因此,目前我一直在使用.NET4.0和WebAPI v1(4.0.30506.0) 有没有办法用旧版本的WebAPI复制RegisterWebAPI()的作用域 虽然我知道nu-get软件包只包含.net 4.5版本,但我能够下载代码并获得一个框架4.0编译,没有太多麻烦。在我的消息处理程序中调用var container=request.GetDependenc

跟进此事。我正在学习使用SimpleInjector和WebAPI的示例。不幸的是,我想利用WebAPI并阻止我升级到.NET4.5。因此,目前我一直在使用.NET4.0和WebAPI v1(4.0.30506.0)

有没有办法用旧版本的WebAPI复制RegisterWebAPI()的作用域

虽然我知道nu-get软件包只包含.net 4.5版本,但我能够下载代码并获得一个框架4.0编译,没有太多麻烦。在我的消息处理程序中调用
var container=request.GetDependencyScope()
时,将返回一个
SimpleInjectorWebApidencyResolver
类。尝试从容器中检索实例,如下所示:

  var poco = (SimplePOCO) container.GetService(typeof(SimplePOCO));
导致以下错误::

SimplePOCO类型的注册委托引发了异常。这个 SimplePOCO已注册为“Web API请求”生活方式,但 实例是在Web API请求的上下文之外请求的

我只是在配置中遗漏了什么吗?还有其他选择吗?比如创建自己的消息处理程序


更新 发帖之后,我又回到了基础。我接受了一个普通的Mvc WebApi项目,引用了我的
SimpleInjector
SimpleInjector.Integration.WebApi
,以及
SimpleInjector.Extensions.ExecutionContextScoping
的编译

像@blueling一样,我能够在消息处理程序中运行它

那有什么不同呢?我的一个想法是,我的非功能项目是赤裸裸的——只有WebApi和slimweb.config。我的解决方案中没有基本项目模板附带的脚手架和绒毛。明天,我计划一次将工作示例与非工作示例逐个引用和web.config设置进行比较


更新2 因此,再进行一点调试,并确保DependencyResolver实现上调用了Dispose(),但我没有


我能够解决这个问题。我不完全清楚为什么会在
SimpleInjectorWebApidencyResolver
上调用dispose,但我发现:

错误的依赖项解析器实现是以下内容的副本:

公共密封类SimpleInjectorWebApidencyResolver:IDependencyResolver
{
专用只读容器;
公共SimpleInjectorWebApidencyResolver(容器)
{
this.container=容器;
}
公共IDependencyScope BeginScope()
{
归还这个;
}
公共对象GetService(类型serviceType)
{
return((IServiceProvider)this.container).GetService(serviceType);
}
公共IEnumerable GetServices(类型serviceType)
{
返回此.container.GetAllInstances(serviceType);
}
公共空间处置()
{
}
}
我注意到我下载的源代码中有一些不同的副本

公共密封类SimpleInjectorWebApidencyResolver:IDependencyResolver
{
专用只读容器;
私有只读范围;
公共SimpleInjectorWebApidencyResolver(容器容器):此(容器,beginScope:false)
{
Requires.IsNotNull(容器,“容器”);
}
私有SimpleInjectorWebApiDependencyResolver(容器容器,bool beginScope)
{
this.container=容器;
if(beginScope)
{
this.scope=container.BeginExecutionContextScope();
}
}
IDependencyScope IDependencyResolver.BeginScope()
{
返回新的SimpleInjectorWebApiDependencyResolver(this.container,beginScope:true);
}
对象IDependencyScope.GetService(类型serviceType)
{
如果(!serviceType.isastract&&typeof(IHttpController).IsAssignableFrom(serviceType))
{
返回此.container.GetInstance(serviceType);
}
return((IServiceProvider)this.container).GetService(serviceType);
}
IEnumerable IDependencyScope.GetServices(类型serviceType)
{
返回此.container.GetAllInstances(serviceType);
}
void IDisposable.Dispose()无效
{
if(this.scope!=null)
{
this.scope.Dispose();
}
}
}

切换到这个版本后,一切正常。正如@Steven在评论中指出的那样,我仍然存在CallContext.LogicalGetData和嵌套执行上下文的潜在问题。因此,使用此解决方案的风险由您自己承担。

您是否注册了
SimpleInjectorWebApidencyResolver
?它已注册。在我的MessageHandler中,检查以下调用
var container=request.GetDependencyScope()
确认类型。如果我使用
WebAPirestLifestyle
SimpleInjectorWebApiDependencyResolver
(通过从
WebRequestLifestyle
SimpleInjectorHttpDependencyResolver
更新),我会产生类似的错误-在我的情况下,实例是在请求之外被请求的,特别是在
Global.asax
initialization
config.MessageHandlers.Add(container.GetInstance())中完成。很乐意帮助测试/调试/跟踪。请注意,我们故意选择不支持.NET 4.0 for Web API,因为
webapirestLifestyle
使用了.NET 4.0下不同的行为。这种行为差异很大,在后台线程中使用嵌套的
ExecutionContextScope
实例时可能会导致错误。为了防止开发人员落入这个陷阱,我们决定只支持.NET 4.5。文档中的期望用户使用
WebRequestLifestyle
,而在后台启动一个新的
ExecutionContextScope
,并且期望用户使用新的
WebApirestLifestyle
。您得到了什么
public sealed class SimpleInjectorWebApiDependencyResolver : IDependencyResolver
{
  private readonly Container container;

  public SimpleInjectorWebApiDependencyResolver(Container container)
  {
    this.container = container;
  }

  public IDependencyScope BeginScope()
  {
    return this;
  }

  public object GetService(Type serviceType)
  {
    return ((IServiceProvider)this.container).GetService(serviceType);
  }

  public IEnumerable<object> GetServices(Type serviceType)
  {
    return this.container.GetAllInstances(serviceType);
 }

 public void Dispose()
 {
 }
}
public sealed class SimpleInjectorWebApiDependencyResolver : IDependencyResolver
{
    private readonly Container container;
    private readonly Scope scope;

    public SimpleInjectorWebApiDependencyResolver(Container container) : this(container, beginScope: false)
    {
        Requires.IsNotNull(container, "container");
    }

    private SimpleInjectorWebApiDependencyResolver(Container container, bool beginScope)
    {
        this.container = container;

        if (beginScope)
        {
            this.scope = container.BeginExecutionContextScope();
        }
    }

    IDependencyScope IDependencyResolver.BeginScope()
    {
        return new SimpleInjectorWebApiDependencyResolver(this.container, beginScope: true);
    }

    object IDependencyScope.GetService(Type serviceType)
    {
        if (!serviceType.IsAbstract && typeof(IHttpController).IsAssignableFrom(serviceType))
        {
            return this.container.GetInstance(serviceType);
        }

        return ((IServiceProvider)this.container).GetService(serviceType);
    }

    IEnumerable<object> IDependencyScope.GetServices(Type serviceType)
    {
        return this.container.GetAllInstances(serviceType);
    }

    void IDisposable.Dispose()
    {
        if (this.scope != null)
        {
            this.scope.Dispose();
        }
    }
}