IoC и dataContext располагаются в приложении asp.net mvc 2 - PullRequest
2 голосов
/ 02 июня 2010

У меня есть Global.asax как код ниже:

public class MvcApplication : System.Web.HttpApplication
{
    public static void RegisterRoutes(RouteCollection routes)
    {
    // ....
    }

    protected void Application_Start()
    {
    AreaRegistration.RegisterAllAreas();

    RegisterRoutes(RouteTable.Routes);

    ControllerBuilder.Current.SetControllerFactory(typeof(IOCControllerFactory));
    }
}

public class IOCControllerFactory : DefaultControllerFactory
{
    private readonly IKernel kernel;

    public IOCControllerFactory()
    {
        kernel = new StandardKernel(new NanocrmContainer());
    }

    protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
    {
        if (controllerType == null)
            return base.GetControllerInstance(requestContext, controllerType);

        var controller = kernel.TryGet(controllerType) as IController;

        if (controller == null)
            return base.GetControllerInstance(requestContext, controllerType);

        var standartController = controller as Controller;

        if (standartController is IIoCController)
            ((IIoCController)standartController).SetIoc(kernel);

        return standartController;
    }

    class NanocrmContainer : Ninject.Modules.NinjectModule
    {
        public override void Load()
        {
            // ...

            Bind<DomainModel.Entities.db>().ToSelf().InRequestScope().WithConstructorArgument("connection", "Data Source=lims;Initial Catalog=nanocrm;Persist Security Info=True;User ID=***;Password=***");
        }
    }
}

В этом случае, если где-то это класс, определенный как:

public class UserRepository : IUserRepository
{
    private db dataContext;
    private IUserGroupRepository userGroupRepository;

    public UserRepository(db dataContext, IUserGroupRepository userGroupRepository)
    {
        this.dataContext = dataContext;
        this.userGroupRepository = userGroupRepository;
    }
}

затем Ninject создает экземпляр dataContext (если никто не был создан в этой области запроса).

Итак, проблема сейчас в том, где вызвать dataContext метод .Dispose()?

UPD

поэтому я последовал совету KeeperOfTheSoul и решил проблему следующим образом:

    public override void ReleaseController(IController controller)
    {
        base.ReleaseController(controller);

        var db = kernel.Get<DomainModel.Entities.db>();
        db.Dispose();
    }

Ответы [ 3 ]

3 голосов
/ 02 июня 2010

Хорошее место, чтобы справиться с этим - IControllerFactory.ReleaseController , например,

public override void ReleaseController() {
    base.ReleaseController();
    //Do whatever you need to clean up the IoC container here
}

В NInject это может быть выполнено путем определения области действия с использованием блока активации , в начале запроса при создании контроллера вы можете сохранить блок активации в текущих элементах HttpContext, во время ReleaseController вы можете получить ранее созданный блок активации и распоряжаться им.

Вы также можете рассмотреть возможность использования InScope и использовать пользовательскую область действия INotifyWhenDisposed. После этого использование будет таким же, как и для блока активации, за исключением того, что теперь вы сохраняете область действия в текущих элементах HttpContext.

2 голосов
/ 02 июня 2010

Шаблон, который иногда используется для удаления соединений БД, заключается в вызове Dispose из финализатора.

public class db : IDisposable {
   //called by the garbage collector 
   ~db() {
     //Call dispose to make sure the resources are cleaned up
     Dispose(false);
   }

   //IDisposable implementation
   public void Dispose() {
     Dispose(true);
   }
   //subclasses of db can override Dispose(bool) and clean up their own fields
   protected virtual void Dispose (bool disposing) {
     if (disposing) {
       //Supress finalization as all resources are released by this method
       //Calling Dispose on IDisposable members should be done here
       GC.SupressFinalize();
     }
     //Clean up unmanaged resources
     //Do not call other objects as they might be already collected if called from the finalizer
   }
}
1 голос
/ 02 июня 2010

Вы можете подключить его к Application_EndRequest.

...