C# 结合Web Api 2.2正确使用Castle Windsor 3.3
我正在开发一个大型ASP.NET Web Api OData应用程序,该应用程序正在Castle Windsor和OWIN startup中使用依赖项注入。实际上,它只向每个控制器中注入实体框架的一个实例,但不知何故,我们得到了一些内存峰值,内存分析器显示问题与实体框架未按预期处理有关 我可以看到该峰值出现在调用.AsNoTracking()中。 我之所以使用它,是因为MSDN提到:“当您的查询用于读取操作时,建议使用NoTracking() 问题在于IIS中的内存使用情况,会执行更多调用,应用程序池会占用更多内存,而且永远不会释放。因此,在几次查询之后,内存会在没有任何逻辑原因的情况下增加到1GB 因此,我将分享我的代码,并寻求建议和评论 网络配置C# 结合Web Api 2.2正确使用Castle Windsor 3.3,c#,asp.net,entity-framework,owin,castle-windsor,C#,Asp.net,Entity Framework,Owin,Castle Windsor,我正在开发一个大型ASP.NET Web Api OData应用程序,该应用程序正在Castle Windsor和OWIN startup中使用依赖项注入。实际上,它只向每个控制器中注入实体框架的一个实例,但不知何故,我们得到了一些内存峰值,内存分析器显示问题与实体框架未按预期处理有关 我可以看到该峰值出现在调用.AsNoTracking()中。 我之所以使用它,是因为MSDN提到:“当您的查询用于读取操作时,建议使用NoTracking() 问题在于IIS中的内存使用情况,会执行更多调用,应用
<modules runAllManagedModulesForAllRequests="true">
<add name="PerRequestLifestyle"
type="Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule, Castle.Windsor" />
</modules>
OWIN启动时
// HttpConfiguration config
IWindsorContainer container = new WindsorContainer();
container.Install(new MyControllersInstaller());
container.Register(Component.For<IWindsorContainer>().Instance(container));
config.DependencyResolver = new WindsorDependencyResolver(container);
//HttpConfiguration配置
IWindsorContainer=新WindsorContainer();
安装(新的MyControllersInstaller());
Register(Component.For().Instance(container));
config.DependencyResolver=新的WindsorDependencyResolver(容器);
温莎依赖项解析程序
public class WindsorDependencyResolver : IDependencyResolver
{
public WindsorDependencyResolver(IWindsorContainer container)
{
this.container = container;
}
private readonly IWindsorContainer container;
public IDependencyScope BeginScope()
{
return new WindsorDependencyScope(container);
}
public void Dispose()
{
container.Dispose();
}
public object GetService(Type serviceType)
{
return container.Kernel.HasComponent(serviceType) ? container.Resolve(serviceType) : null;
}
public IEnumerable<object> GetServices(Type serviceType)
{
return container.ResolveAll(serviceType).Cast<object>();
}
}
public class MvcInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(Classes.FromAssembly(typeof(MyController).Assembly)
.BasedOn<ODataController>()
.LifestylePerWebRequest());
container.Register(
Component
.For<DbContext>()
.ImplementedBy<MyEfContext>()
.LifestylePerWebRequest());
}
}
public class PersonsController : ODataController
{
public PersonsController(DbContext session)
{
this.session = session;
}
private readonly ICommandDispatcher commandDispatcher;
private readonly DbContext session;
public IQueryable<Person> Get()
{
return session
.Set<Person>()
.AsNoTracking();
}
public SingleResult<Person> Get([FromODataUri] Guid key)
{
return SingleResult.Create(session
.Set<Person>()
.AsNoTracking()
.Where(x => x.Id == key));
}
}
公共类WindsorDependencyResolver:IDependencyResolver
{
公共风电场风电场风电场风电场风电场风电场风电场风电场风电场风电场风电场风电场风电场风电场风电场风电场风电场风电场风电场风电场风电场风电场风电场风电场风电场风电场风电场风电场风电场风电场风电场风电场风电场
{
this.container=容器;
}
私有只读IWindsorContainer;
公共IDependencyScope BeginScope()
{
退回新的风向标(集装箱);
}
公共空间处置()
{
container.Dispose();
}
公共对象GetService(类型serviceType)
{
返回container.Kernel.HasComponent(serviceType)?container.Resolve(serviceType):null;
}
公共IEnumerable GetServices(类型serviceType)
{
返回container.ResolveAll(serviceType.Cast();
}
}
温莎依赖范围
public class WindsorDependencyScope : IDependencyScope
{
public WindsorDependencyScope(IWindsorContainer container)
{
this.container = container;
this.scope = container.BeginScope();
}
private readonly IWindsorContainer container;
private readonly IDisposable scope;
public void Dispose()
{
this.scope.Dispose();
}
public object GetService(Type serviceType)
{
if (container.Kernel.HasComponent(serviceType))
{
return container.Resolve(serviceType);
}
else
{
return null;
}
}
public IEnumerable<object> GetServices(Type serviceType)
{
return this.container.ResolveAll(serviceType).Cast<object>();
}
}
public class WindsorDependencyScope:IDependencyScope
{
公共风向仪(IWindsorContainer)
{
this.container=容器;
this.scope=container.BeginScope();
}
私有只读IWindsorContainer;
私有只读IDisposable作用域;
公共空间处置()
{
this.scope.Dispose();
}
公共对象GetService(类型serviceType)
{
if(container.Kernel.HasComponent(serviceType))
{
返回容器解析(serviceType);
}
其他的
{
返回null;
}
}
公共IEnumerable GetServices(类型serviceType)
{
返回此.container.ResolveAll(serviceType.Cast();
}
}
控制器+EF安装程序
public class WindsorDependencyResolver : IDependencyResolver
{
public WindsorDependencyResolver(IWindsorContainer container)
{
this.container = container;
}
private readonly IWindsorContainer container;
public IDependencyScope BeginScope()
{
return new WindsorDependencyScope(container);
}
public void Dispose()
{
container.Dispose();
}
public object GetService(Type serviceType)
{
return container.Kernel.HasComponent(serviceType) ? container.Resolve(serviceType) : null;
}
public IEnumerable<object> GetServices(Type serviceType)
{
return container.ResolveAll(serviceType).Cast<object>();
}
}
public class MvcInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(Classes.FromAssembly(typeof(MyController).Assembly)
.BasedOn<ODataController>()
.LifestylePerWebRequest());
container.Register(
Component
.For<DbContext>()
.ImplementedBy<MyEfContext>()
.LifestylePerWebRequest());
}
}
public class PersonsController : ODataController
{
public PersonsController(DbContext session)
{
this.session = session;
}
private readonly ICommandDispatcher commandDispatcher;
private readonly DbContext session;
public IQueryable<Person> Get()
{
return session
.Set<Person>()
.AsNoTracking();
}
public SingleResult<Person> Get([FromODataUri] Guid key)
{
return SingleResult.Create(session
.Set<Person>()
.AsNoTracking()
.Where(x => x.Id == key));
}
}
公共类MvcInstaller:IWindsorInstaller
{
public void安装(IWindsorContainer、IConfigurationStore)
{
container.Register(Classes.fromsassembly)(typeof(MyController.Assembly)
.BasedOn()
.LifestylePerWebRequest());
集装箱。登记(
组成部分
.对于()
.由()实施
.LifestylePerWebRequest());
}
}
ODATA控制器
public class WindsorDependencyResolver : IDependencyResolver
{
public WindsorDependencyResolver(IWindsorContainer container)
{
this.container = container;
}
private readonly IWindsorContainer container;
public IDependencyScope BeginScope()
{
return new WindsorDependencyScope(container);
}
public void Dispose()
{
container.Dispose();
}
public object GetService(Type serviceType)
{
return container.Kernel.HasComponent(serviceType) ? container.Resolve(serviceType) : null;
}
public IEnumerable<object> GetServices(Type serviceType)
{
return container.ResolveAll(serviceType).Cast<object>();
}
}
public class MvcInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(Classes.FromAssembly(typeof(MyController).Assembly)
.BasedOn<ODataController>()
.LifestylePerWebRequest());
container.Register(
Component
.For<DbContext>()
.ImplementedBy<MyEfContext>()
.LifestylePerWebRequest());
}
}
public class PersonsController : ODataController
{
public PersonsController(DbContext session)
{
this.session = session;
}
private readonly ICommandDispatcher commandDispatcher;
private readonly DbContext session;
public IQueryable<Person> Get()
{
return session
.Set<Person>()
.AsNoTracking();
}
public SingleResult<Person> Get([FromODataUri] Guid key)
{
return SingleResult.Create(session
.Set<Person>()
.AsNoTracking()
.Where(x => x.Id == key));
}
}
公共类PersonController:ODataController
{
公共PersonsController(DbContext会话)
{
this.session=会话;
}
专用只读ICommandDispatcher命令Dispatcher;
专用只读DbContext会话;
公共IQueryable Get()
{
返回会话
.Set()
.AsNoTracking();
}
公共单结果获取([FromODataUri]Guid键)
{
返回SingleResult.Create(会话
.Set()
.AsNoTracking()
。其中(x=>x.Id==key));
}
}
我建议这篇文章可能会得到更多的关注和更好的回复。它看起来像是关于代码审查。您正在使用“PerWebRequest”生活方式。您的web.config中是否配置了Windsor PerWebRequestLifestyleModule HTTP模块?没有它,Windsor无法在请求结束时发布组件……我有@MichalLevý,但在Azure上它似乎无法工作。它可以在Windows 2012 IIS 7和8上运行,但在Azure的web应用程序中它不会处理任何内容:-(@Raffaeu你能用web.config的相关部分来更新你的问题吗?但是模块注册可能是可以的,因为你会从Castle Otherwise那里得到一个例外。我建议这篇文章可能会得到更多的关注和更好的回复。它看起来像是关于代码审查。你使用的是“PerWebRequest”生活方式。您的web.config中是否配置了Windsor PerWebRequestLifestyleModule HTTP模块?如果没有它,Windsor将无法在请求结束时发布组件…我有@MichalLevý,但在Azure上它似乎不起作用。它在Windows 2012 IIS 7和8上起作用,但在Azure的web应用中它不会处理任何东西:-(@Raffaeu您可以用web.config的相关部分更新您的问题以确定吗?但是模块注册可能是可以的,因为否则您将从Castle获得异常