2013-07-16 41 views
1

我是新在这(我还在学习),我想,如果你绝地大师在那里可以帮助我走出这个问题和关注很欣赏我有。Ninject瞬态范围+范围处置+垃圾收集+内存泄漏

我想使用Ninject,我有下面的代码,我想知道是否我的物体会妥善处理和垃圾收集。

对于Ninject的默认瞬态范围,我读了“终身不被内核管理(该范围对象为空),并永远不会被处理完毕。”

如果我会用我的代码在生产,特别是当我得到很多并发呼叫我的WebAPI(POST),它会导致像内存泄漏等任何问题?

什么是最好的Ninject的对象范围用于这种情况?

顺便说一句,如果我不喜欢指定对象范围“kernel.Bind()至();”,将默认为TransientScope?

public class VehicleClassRepository : IVehicleClassRepository 
{ 
    SomeDataContext context = new SomeDataContext(); 

    public IQueryable<VehicleClass> All 
    { 
     get { return context.VehicleClasses; } 
    } 

    public IQueryable<VehicleClass> AllIncluding(params Expression<Func<VehicleClass, object>>[] includeProperties) 
    { 
     IQueryable<VehicleClass> query = context.VehicleClasses; 
     foreach (var includeProperty in includeProperties) { 
      query = query.Include(includeProperty); 
     } 
     return query; 
    } 

    public VehicleClass Find(int id) 
    { 
     return context.VehicleClasses.Find(id); 
    } 

    public void InsertOrUpdate(VehicleClass vehicleclass) 
    { 
     if (vehicleclass.VehicleClassId == default(int)) { 
      // New entity 
      context.VehicleClasses.Add(vehicleclass); 
     } else { 
      // Existing entity 
      context.Entry(vehicleclass).State = EntityState.Modified; 
     } 
    } 

    public void Delete(int id) 
    { 
     var vehicleclass = context.VehicleClasses.Find(id); 
     context.VehicleClasses.Remove(vehicleclass); 
    } 

    public void Save() 
    { 
     context.SaveChanges(); 
    } 

    public void Dispose() 
    { 
     context.Dispose(); 
    } 
} 

public interface IVehicleClassRepository : IDisposable 
{ 
    IQueryable<VehicleClass> All { get; } 
    IQueryable<VehicleClass> AllIncluding(params Expression<Func<VehicleClass, object>>[] includeProperties); 
    VehicleClass Find(int id); 
    void InsertOrUpdate(VehicleClass vehicleclass); 
    void Delete(int id); 
    void Save(); 
} 

在我NinjectWebCommon.cs:

private static void RegisterServices(IKernel kernel) 
    { 
     kernel.Bind<IVehicleClassRepository>().To<VehicleClassRepository>(); 
    } 

在我的WebAPI的VehicleClassController.cs:

public HttpResponseMessage Post(VehicleClass value) 
{ 
     if (value == null) 
     { 
      return new HttpResponseMessage(HttpStatusCode.BadRequest); 
     } 
     else 
     { 
      vehicleclassRepository.InsertOrUpdate(value); 
      vehicleclassRepository.Save(); 
      return new HttpResponseMessage(HttpStatusCode.Created); 
     } 
} 
+1

是的,如果您没有指定范围,则默认为瞬态范围。 瞬态范围意味着ninject不保留对创建对象的引用。只要你不再提及它,它就会被GC收集垃圾。 – BatteryBackupUnit

+0

BatteryBackupUnit:谢谢你的澄清...如果它没有保留对创建对象的引用...我的代码应该是安全的内存泄漏,然后呢?使用InRequestScope会更好吗? – Peter

+0

是的,除非你保持一个比需要更长的引用,瞬态范围意味着不会有内存泄漏。 – BatteryBackupUnit

回答

1

迟到的回答(近2年),但在其他情况下,读这...

尽管垃圾收集器最终会处理您的VehicleClassRepositor例如,你很可能在那之前遇到问题。

您的数据上下文可能会保留一个打开的数据库连接,直到它被丢弃。数据库连接可能来自数据库连接池。

这么久的CLR结束了垃圾回收这些(这也将处理掉),传入的请求结束,而试图获得一个数据库连接,但没有符合条件的阻塞之前。

我遇到过这种类型的行为,并从中学到了困难的方法。因此,VehicleClassRepository应该在依赖范围内定义范围,以便每次调用都能获得一个,更重要的是,它将在调用完成后立即处理。