C# 使用asp.net Web Api实现StructureMap的性能
在使用WebApi的asp.NETMVC4项目中,我也使用Structuremap(2.6.4.1)作为IoC容器。它按照最佳实践连接到web站点,这里没有什么特别之处 当我使用密集的依赖项解析时,我有大约500个定义(这是主管道图中InstanceFactory实例的数量) 在本地运行自定义探查器或使用asp.net探查器运行负载测试会导致相同的结果:GetNestedContainer是一个CPU消耗操作(大约25%)。这不是我想的,这是我测量过的。从另一个基本测试来看,围绕GetNestedContainer的简单秒表大约需要15毫秒(当我的web api操作需要40毫秒时) GetNestedContainer在我的代码中只调用一次:在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
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;
}