Using an IOC Container in MVC3, are objects shared

2019-09-01 00:43发布

问题:

I've read several articles explaining the use of static classes in a MVC webapplication. From these articles I've created a small example to prove that the static variables are really shared between user sessions.

I've logged in to my site using 2 different browsers, windows authentication and 2 different user accounts. A specific variable is being set when a user has logged in, if the variable is null. After the first user has logged in the variable = 1. When I access this when user 2 starts his session I can clearly see this still = 1 as expected. So far it works fine.

The real question is: We are using a class for IOC named MemoryContainer. Since parts of this Memorycontainer class are static, are the classes registered in this container also shared between user sessions in mvc?

The complete code:

public class MemoryContainer
{
    #region Singleton
    private static volatile MemoryContainer instance;
    private static object syncRoot = new Object();

    private MemoryContainer()
    {}

    private void Initialize()
    {
        myContainer = new Dictionary<Type, object>();
    }

    public static MemoryContainer Instance
    {
        get
        {
            if (instance == null)
            {
                lock (syncRoot)
                {
                    if (instance == null)
                    {
                        instance = new MemoryContainer();
                        instance.Initialize();
                    }
                }
            }

            return instance;
        }
    }
    #endregion

    Dictionary<Type, object> myContainer = null;

    private Dictionary<Type, object> Container
    {
        get { return this.myContainer; }            
    }

    public void RegisterInstance(Type type, object instance)
    {
        if (!myContainer.ContainsKey(type))
            myContainer.Add(type, instance);

    }

    public void UpdateInstance(Type type, object newInstance)
    {
        if (this.myContainer.ContainsKey(type))
            myContainer[type] = newInstance;
    }

    public T Resolve<T>(Type t) where T : class
    {            
        T item =  (T) myContainer[t];
        myContainer.Remove(t);
        return item;
    }

    public T TryResolve<T>(Type t) where T : class
    {
        if (this.myContainer.ContainsKey(t))
            return (T) Resolve<T>(t);
        return null;
    }

    public T Peek<T>(Type t) where T : class
    { 
        if (this.myContainer.ContainsKey(t))
            return (T) myContainer[t];
        return null;
    }
}

回答1:

Since you are using the singleton pattern, only one instance of the MemoryContainer class will ever be created. This means that whenever you touch the Instance property you are always pointing to the same location in memory. So multiple users will share the same data.

Also it should be noted that since this classes uses a Dictionary<TKey, TValue> for internal storage, this class is not thread-safe and should not be used in a multithreaded environment such as an ASP.NET application unless you properly synchronize the access to this resource or using a thread-safe data structure (such as a ConcurrentDictionary<TKey, TValue> for example). So this custom built IoC container is fine but should not be used in a multithreaded application without making it thread-safe.