views:

68

answers:

1

first I want to say that I hope this doesn't look like I am lazy but I have some trouble understanding a piece of code from the following project.

http://kigg.codeplex.com/

I was going through the source code and I noticed something that would be usefull for my own little project I am making. In their BaseController they have the following code:

private static readonly Type CurrentUserKey = typeof(IUser);

public IUser CurrentUser
{
    get
    {
        if (!string.IsNullOrEmpty(CurrentUserName))
        {
            IUser user = HttpContext.Items[CurrentUserKey] as IUser;

            if (user == null)
            {
                user = AccountRepository.FindByClaim(CurrentUserName);

                if (user != null) 
                {
                    HttpContext.Items[CurrentUserKey] = user; 
                }
            }

            return user;
        }

        return null;
    }
}

This isn't an exact copy of the code I adjusted it a little to my needs. This part of the code I still understand. They store their IUser in HttpContext.Items. I guess they do it so that they don't have to call the database eachtime they need the User object.

The part that I don't understand is how they maintain this object in between requests. If I understand correctly the HttpContext.Items is a per request cache storage.

So after some more digging I found the following code.

internal static IDictionary<UnityPerWebRequestLifetimeManager, object> GetInstances(HttpContextBase httpContext)
{
    IDictionary<UnityPerWebRequestLifetimeManager, object> instances;

    if (httpContext.Items.Contains(Key))
    {
        instances = (IDictionary<UnityPerWebRequestLifetimeManager, object>) httpContext.Items[Key];
    }
    else
    {
        lock (httpContext.Items)
        {
            if (httpContext.Items.Contains(Key))
            {
                instances = (IDictionary<UnityPerWebRequestLifetimeManager, object>) httpContext.Items[Key];
            }
            else
            {
                instances = new Dictionary<UnityPerWebRequestLifetimeManager, object>();
                httpContext.Items.Add(Key, instances);
            }
        }
    }

    return instances;
}

This is the part where some magic happens that I don't understand. I think they use Unity to do some dependency injection on each request? In my project I am using Ninject and I am wondering how I can get the same result.

I guess InRequestScope in Ninject is the same as UnityPerWebRequestLifetimeManager? I am also wondering which class/method they are binding to which interface? Since the HttpContext.Items get destroyed each request how do they prevent losing their user object?

Anyway it's kinda a long question so I am grateful for any push in the right direction.

A: 

In Ninject, you pick your tech-specific extension (Ninject.Web or Ninject.Web.Mvc) and use InRequestScope to manage stuff in 'the .Items context'. They get Disposed at the end of the request and fresh ones will be Resolved as needed on subsequent requests.

It definitely wont be as much code or as complex as some of the stuff you're citing IMO :D

Ruben Bartelink
Read some information about Kigg and Unity and now I ain't sure what that last piece of code does. I think I am also wrong about that they keep the User object between requests. I guess they store it in HttpContext.Items so that they have to call the database only once for each request.
Pickels
Items is not between requests - only session can do that. Items is for example if you do async work and move onto another thread - tis a place to store stuff between diffent phases of processing a single HTTP request. (Hence my comparing InRequestScope to Items)
Ruben Bartelink