Подтвердить что ты не робот

Ninject не вызывает Dispose на объектах, когда выходит из сферы действия

Я с удивлением обнаружил, что по крайней мере один из моих объектов, созданных Ninject, не удаляется в конце запроса, когда он был определен как InRequestScope

Здесь объект, который я пытаюсь утилизировать:

Интерфейс:

public interface IDataContext : IDisposable
{
    MessengerEntities context { get; set; }
}

MessengerEntities - реализация Entity Framework объекта ObjectContext - моего контекстного объекта.

Затем я создаю конкретный класс следующим образом:

public class DataContext : IDataContext
{
    private MessengerEntities _context = new MessengerEntities();
    public MessengerEntities context
    {
        get
        {
            return _context;
        }
        set
        {
            _context = value;
        }
    }
    #region IDisposable Members

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

    #endregion
}

И тогда у меня есть контроллер Ninject factory, как это (это смоделировано на книге Стив Сандерсон MVC 2):

public class NinjectControllerFactory : DefaultControllerFactory
{
    // a Ninject "kernel" is the thing that can supply object instances
    private IKernel kernel = new StandardKernel(new MessengerServices());

    // ASP.NET MVC calls this to get the controller for each request
    protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
    {
        if (controllerType == null)
            return null;
        return (IController)kernel.Get(controllerType);
    }

    private class MessengerServices : NinjectModule
    {
        public override void Load()
        {
            Bind<IDataContext>().To<DataContext>().InRequestScope();
            Bind<IArchivesRepository>().To<ArchivesRepository>().InRequestScope();
            Bind<IMessagesRepository>().To<MessagesRepository>().InRequestScope();
        }
    }
}

Теперь, когда я ставлю точку останова при вызове контекста. Dispose() в объекте DataContext и запустите отладчик, этот код никогда не будет выполнен.

Итак, данные свидетельствуют о том, что Ninject не уничтожает объекты, когда они выходят из сферы действия, но просто создает новые объекты и полагается на сборщик мусора, чтобы избавиться от них в момент его выбора.

Мой вопрос: должен ли я беспокоиться об этом? Потому что я - я бы подумал, что Ninject будет распоряжаться любым объектом, который реализует IDisposable.

ОБНОВЛЕНИЕ: Я загрузил расширения Ninject Mvc (для MVC 3), и теперь это то, как я делаю MvcApplication и привязку, и похоже, что он удаляет мой объект контекста.

В global.asax:

public class MvcApplication : NinjectHttpApplication
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new HandleErrorAttribute());
    }

    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(
            "Default", // Route name
            "{controller}/{action}/{id}", // URL with parameters
            new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
        );

    }

    protected override Ninject.IKernel CreateKernel()
    {
        var kernel = new StandardKernel();
        kernel.Load(Assembly.GetExecutingAssembly());
        return kernel;
    }

    protected override void OnApplicationStarted()
    {
        base.OnApplicationStarted();
        AreaRegistration.RegisterAllAreas();
        RegisterGlobalFilters(GlobalFilters.Filters);
        RegisterRoutes(RouteTable.Routes);
    }
}

и

public class EFBindingModule : NinjectModule
{
    public override void Load()
    {
        Bind<IDataContext>().To<DataContext>().InRequestScope();
        Bind<IArchivesRepository>().To<ArchivesRepository>().InRequestScope();
        Bind<IMessagesRepository>().To<MessagesRepository>().InRequestScope();
    }
}

Все остальное остается прежним.

4b9b3361

Ответ 1

Ninject будет располагать ваши объекты, как только объект запроса будет собран GC. Но обычно это занимает некоторое время. Но есть способ принудительного досрочного освобождения после окончания запроса. Лучше всего использовать Ninject.Web.MVC http://www.planetgeek.ch/2010/11/13/official-ninject-mvc-extension-gets-support-for-mvc3/ вместо реализации собственного ControllerFactory. Другой способ - настроить приложение для использования OnePerRequestModule.