DbContext Unity не вызывает HttpContextLifetimeManager.RemoveValue () Плохая вещь? - PullRequest
2 голосов
/ 08 марта 2012

Я определяю свой DbConntextObj

_container.RegisterType<IDbConntextObj, DbConntextObj>(new HttpContextLifetimeManager<DbConntextObj>());

Unity не вызывает RemoveValue () для менеджера времени жизни

У меня есть один Dbcontext для нескольких репозиториев.

Mylifemanager выглядит следующим образом:

public class HttpContextLifetimeManager<T> : LifetimeManager, IDisposable
    {
        private readonly string _itemName = typeof(T).AssemblyQualifiedName;

        public override object GetValue()
        {
            return HttpContext.Current.Items[_itemName];
        }
        public override void RemoveValue()
        {
            var disposable = GetValue() as IDisposable;
            HttpContext.Current.Items.Remove(_itemName);

            if (disposable != null)
                disposable.Dispose();
        }

        public override void SetValue(object newValue)
        {
            HttpContext.Current.Items[_itemName] = newValue;
        }
        public void Dispose()
        {
            RemoveValue();
        }
    }

Это плохо, что DbContext Dispose не вызывается?Есть ли обходной путь для Unity и MVC3?

1 Ответ

0 голосов
/ 08 марта 2012

Попробуйте это.

    public class MvcApplication : HttpApplication
{
    private IUnityContainer unityContainer;
    private HttpContextDisposableLifetimeManager ContextLifeTimeManager;
    /// <summary>
    /// The start method of the application.
    /// </summary>
    protected void Application_Start()
    {
        unityContainer = new UnityContainer();
        ContextLifeTimeManager = new HttpContextDisposableLifetimeManager();
        //for some reason this event handler registration doesn't work, meaning we have to add code to
        //Application_EndRequest as below...
        //this.EndRequest += new EventHandler(ContextLifeTimeManager.DisposingHandler);
        unityContainer.RegisterType<IUnitOfWork, EFUnitOfWork>(ContextLifeTimeManager);
        unityContainer.RegisterType<IRepository<ShoppingCart>, ShoppingCartRepository>(new ContainerControlledLifetimeManager());
    }
    //this seems hackish, but it works, so whatever...
    protected void Application_EndRequest(Object sender, EventArgs e)
    {
        if (ContextLifeTimeManager != null)
        {
            ContextLifeTimeManager.RemoveValue();
        }
    }
}

Затем в вашей реализации LifeTimeManager.

public class HttpContextDisposableLifetimeManager : LifetimeManager, IDisposable
{        
    const string _itemName = typeof(T).AssemblyQualifiedName;

    public void DisposingHandler(object source, EventArgs e)
    {
        RemoveValue();
    }

    public override object GetValue()
    {
        return HttpContext.Current.Items[_itemName];
    }
    public override void RemoveValue()
    {
        Dispose();
        HttpContext.Current.Items.Remove(_itemName);
    }

    public override void SetValue(object newValue)
    {
        HttpContext.Current.Items[_itemName] = newValue;
    }
    public void Dispose()
    {
        var obj = (IDisposable)GetValue();
        obj.Dispose();
    }
}
...