Question

I'm trying to clean up the default implementation of AccountController.cs that comes out of the box in the new MVC5/Owin security implementation. I have modified my constructor to look like this:

private UserManager<ApplicationUser> UserManager;
public AccountController(UserManager<ApplicationUser> userManager)
{
    this.UserManager = userManager;
}

Also, I have created a lifetime manager for Unity that looks like this:

 public class HttpContextLifetimeManager<T> : LifetimeManager, IDisposable
    {
        private HttpContextBase _context = null;
        public HttpContextLifetimeManager()
        {
            _context = new HttpContextWrapper(HttpContext.Current);
        }
        public HttpContextLifetimeManager(HttpContextBase context)
        {
            if (context == null)
                throw new ArgumentNullException("context");
            _context = context;
        }
        public void Dispose()
        {
            this.RemoveValue();
        }
        public override object GetValue()
        {
            return _context.Items[typeof(T)];
        }
        public override void RemoveValue()
        {
            _context.Items.Remove(typeof(T));
        }
        public override void SetValue(object newValue)
        {
            _context.Items[typeof(T)] = newValue;
        }
    }

I'm not sure how to write this in my UnityConfig.cs, but this is what I have so far:

container.RegisterType<UserManager<ApplicationUser>>(new HttpContextLifetimeManager(new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new RecipeManagerContext()))));

I did find another example (using AutoFac) that does it this way:

container.Register(c => new UserManager<ApplicationUser>(new UserStore<ApplicationUser>( new RecipeManagerContext())))
                .As<UserManager<ApplicationUser>>().InstancePerHttpRequest();

How would I translate the above statement using Unity IoC lifetime management?

Était-ce utile?

La solution

Your approach where the UserManager is registered for specific lifetime is correct. However, I don't understand why it even compiles, since your HttpContextLifetimeManager expects the HttpContext as a parameter.

Another issue is that your implementation is wrong. The parameterless constructor takes current http context, however you rather want the lifetime manager to use the context the instance is created on rather the one the type is registered on. If the parameterless constructor is used, this could lead to http context mismatch issues.

First, change your implementation to

public class HttpContextLifetimeManager : LifetimeManager
{
 private readonly object key = new object();

 public override object GetValue()
 {
     if (HttpContext.Current != null && 
         HttpContext.Current.Items.Contains(key))
         return HttpContext.Current.Items[key];
     else
         return null;
 }

 public override void RemoveValue()
 {
     if (HttpContext.Current != null)
         HttpContext.Current.Items.Remove(key);
 }

 public override void SetValue(object newValue)
 {
     if (HttpContext.Current != null)
         HttpContext.Current.Items[key] = newValue;
 }
}

and then register your type

container.RegisterType<UserManager<ApplicationUser>>( new HttpContextLifetimeManager() );
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top