Factory.cs :  » Game » SokoSolve-Sokoban » SokoSolve » Common » FactoryPattern » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » Game » SokoSolve Sokoban 
SokoSolve Sokoban » SokoSolve » Common » FactoryPattern » Factory.cs
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Security.Permissions;
using System.Text;

namespace SokoSolve.Common.FactoryPattern{
    /// <summary>
    /// In implementation of the factory class design pattern
    /// </summary>
    /// <typeparam name="Provider">Provider which who instances are factory made by this class</typeparam>
    /// <typeparam name="ProviderContext">The key or context used to build a Provider</typeparam>
    public abstract class Factory<Provider, ProviderContext> : IFactory<Provider, ProviderContext>
    {
        private Dictionary<ProviderContext, Provider> cache;
        private object cacheLock = new object();
        public Factory()
        {
            cache = new Dictionary<ProviderContext, Provider>();
        }

        /// <summary>
        /// Get the number of instances in the factory (note this is lazy loading)
        /// </summary>
        public int InstanceCount
        {
            get
            {
                return cache.Count;
            }
        }

        /// <summary>
        /// All instances currently in the cache
        /// </summary>
        public virtual List<Provider> Instances
        {
            get
            {
                List<Provider> allInstances = new List<Provider>(cache.Values);
                return allInstances;
            }
        }

        /// <summary>
        /// Can this factory create an instance for the following context? 
        /// Note: This method will lazy-load to check if this instance exists, it does not just check the cache.
        /// </summary>
        /// <param name="providerContext"></param>
        /// <returns></returns>
        public virtual bool Contains(ProviderContext providerContext)
        {
            return GetInstance(providerContext) != null;
        }

        /// <summary>
        /// Init the cache with pre-created instances
        /// </summary>    
        protected void Init(Provider newProvider, ProviderContext creationContext)
        {
            cache.Add(creationContext, newProvider);
        }

        /// <summary>
        /// Key method. This method is responsible for returning or loading and returning a valid instance of Provider based on ProviderContext
        /// </summary>
        /// <param name="creationContext"></param>
        /// <returns></returns>
        public virtual Provider GetInstance(ProviderContext creationContext)
        {
            lock (cacheLock)
            {
                if (creationContext == null) throw new ArgumentNullException("providerContext");

                // Reflection vodoo and validation
                if (cache.ContainsKey(creationContext))
                {
                    return cache[creationContext];
                }
                else
                {
                    // Create
                    Provider newInstance = CreateInstance(creationContext);
                    if (newInstance == null)
                    {
                        throw new ArgumentNullException("newInstance");
                    }

                    cache.Add(creationContext, newInstance);

                    return newInstance;
                }
            }
        }

        /// <summary>
        /// Default implementation of creation which used reflection to create an instance of Provider
        /// </summary>
        /// <param name="creationContext"></param>
        /// <returns></returns>
        [PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
        protected virtual Provider CreateInstance(ProviderContext creationContext)
        {
            try
            {
                Type providerType = GetProviderType(creationContext);
                if (providerType == null) throw new ArgumentNullException("Cannot find type for creationContext");
                Provider newInstance = (Provider)Activator.CreateInstance(providerType);
                if (newInstance == null)
                {
                    throw new ArgumentNullException(string.Format("Cannot create a new instance of {0} of type {1}", creationContext, creationContext.GetType()));
                }
                Type typeProvider = typeof (Provider);
                List<Type> typesCreated = new List<Type>();
                typesCreated.Add(newInstance.GetType());
                typesCreated.AddRange(newInstance.GetType().GetNestedTypes());
                typesCreated.AddRange(newInstance.GetType().GetInterfaces());
                if (!typesCreated.Contains(typeProvider))
                {
                    throw new ArgumentNullException(string.Format("Create new instance, however it is of the wrong type. Expected {0}, but got {1}", typeof(Provider), newInstance.GetType()));
                }
                return newInstance;
            }
            catch (TargetInvocationException tiEx)
            {
                throw new ArgumentException(string.Format("Cannot create a new instance of {0} of type {1}", creationContext, creationContext.GetType())+tiEx.Message, tiEx);
            }
         }

        /// <summary>
        /// Based on the ProviderContext return the Type to be created
        /// </summary>
        /// <param name="providerContext"></param>
        /// <returns></returns>
        protected virtual Type GetProviderType(ProviderContext providerContext)
        {
           string providerNamespace = GetProviderClassNamespace(providerContext);
            if (providerNamespace == null)
            {
                throw new ArgumentNullException("providerNamespace");
            }

            // Try the current assembly
            Type typeResult = Type.GetType(providerNamespace, false, true);
            if (typeResult != null) return typeResult;

            // Try all loaded assemblies
            string searchlist = "";
            foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies())
            {
                searchlist += asm.FullName + " ";
                typeResult = asm.GetType(providerNamespace, false, true);
                if (typeResult != null) return typeResult;
            }

            throw new Exception("Cannot find type in any of the following assemblies: " + searchlist);
        }

        /// <summary>
        /// Helper method. Converts a ProviderContext into the type namespace for the class to be created. 
        /// This is just a short-cut to using the Type class which is strongly typed, but has more overhead/developer work in creating.
        /// </summary>
        /// <param name="providerContext"></param>
        /// <returns></returns>
        protected virtual string GetProviderClassNamespace(ProviderContext providerContext)
        {
            throw new NotSupportedException("Override GetProviderClassNamespace(...)");
        }

        /// <summary>
        /// Does the cache already contain an Provider for a ProviderContext
        /// </summary>
        /// <param name="providerContext"></param>
        /// <returns></returns>
        protected bool CacheContains(ProviderContext providerContext)
        {
            return cache.ContainsKey(providerContext);
        }
    }
}
www.java2v.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.