C# 使用asp.net Web Api实现StructureMap的性能

C# 使用asp.net Web Api实现StructureMap的性能,c#,asp.net-mvc,asp.net-web-api,inversion-of-control,structuremap,C#,Asp.net Mvc,Asp.net Web Api,Inversion Of Control,Structuremap,在使用WebApi的asp.NETMVC4项目中,我也使用Structuremap(2.6.4.1)作为IoC容器。它按照最佳实践连接到web站点,这里没有什么特别之处 当我使用密集的依赖项解析时,我有大约500个定义(这是主管道图中InstanceFactory实例的数量) 在本地运行自定义探查器或使用asp.net探查器运行负载测试会导致相同的结果:GetNestedContainer是一个CPU消耗操作(大约25%)。这不是我想的,这是我测量过的。从另一个基本测试来看,围绕GetNeste

在使用WebApi的asp.NETMVC4项目中,我也使用Structuremap(2.6.4.1)作为IoC容器。它按照最佳实践连接到web站点,这里没有什么特别之处

当我使用密集的依赖项解析时,我有大约500个定义(这是主管道图中InstanceFactory实例的数量)

在本地运行自定义探查器或使用asp.net探查器运行负载测试会导致相同的结果:GetNestedContainer是一个CPU消耗操作(大约25%)。这不是我想的,这是我测量过的。从另一个基本测试来看,围绕GetNestedContainer的简单秒表大约需要15毫秒(当我的web api操作需要40毫秒时)

GetNestedContainer在我的代码中只调用一次:在
System.Web.Http.Dependencies.IDependencyResolver
的my/structuremap实现中

public IDependencyScope BeginScope()
{
    IContainer child = this.Container.GetNestedContainer();
    return new StructureMapHttpDependencyResolver(child);
}
只是为了好玩,在反编译了这段代码之后,我理解了为什么它这么慢:锁,在所有InstanceFactory上的迭代,甚至反射(克隆内部)

//来自structuremap
公共管线图ToNestedGraph()
{
PipelineGraph clone=新管道图(this.\u profileManager.clone()、this.\u GenericGraph.clone()、this.\u日志)
{
_missingFactory=这个
};
监视。输入(此);
尝试
{
foreach(此.\u工厂中的KeyValuePair对)
{
clone._factories.Add(pair.Key,pair.Value.clone());
}
}
最后
{
监控。退出(本);
}
clone.EjectAllInstancesOf();
返回克隆;
}
使用asp.net web api时,会为每个请求调用BeginScope。由于实时显示,我有很多ajax请求,所以我遇到了一个严重的瓶颈。structureMap真的与asp.net Web Api兼容吗

我能做些什么来改进这一点


我想到的第一个想法是减少InstanceFactory定义的数量。这并不容易,因为我的实现之间有很多依赖关系。即使有200个定义,其影响也将十分重要。不幸的是,StructureMap似乎禁止多个根容器(一个用于MVC,一个用于WebApi)

Structuremap禁止多个根容器是什么意思
ObjectFactory
只是一个默认的静态容器,如果您不想处理自己的实例,可以使用它。没有什么可以阻止您创建自己的容器集。只需调用
newcontainer(c=>{…})
并创建所需的容器。@PHeiberg完全正确。我只是使用
ObjectFactory
作为默认的容器工厂。首先尝试使用多个容器是有希望的。但是,我仍然对大量绑定的SM性能没有信心。
//from structuremap
public PipelineGraph ToNestedGraph()
{
    PipelineGraph clone = new PipelineGraph(this._profileManager.Clone(), this._genericsGraph.Clone(), this._log)
    {
        _missingFactory = this._missingFactory
    };
    Monitor.Enter(this);
    try
    {
        foreach (KeyValuePair<Type, IInstanceFactory> pair in this._factories)
        {
            clone._factories.Add(pair.Key, pair.Value.Clone());
        }
    }
    finally
    {
        Monitor.Exit(this);
    }
    clone.EjectAllInstancesOf<IContainer>();
    return clone;
}