Changeset 2132


Ignore:
Timestamp:
5/15/2010 2:50:31 PM (4 years ago)
Author:
lowjoel
Message:

Implemented a new FactoryRegistrar? class which is a registrar, but creates new instances of every object upon enumeration so that multiple copies of the class can exist at any one time.

Location:
trunk/eraser/Eraser.Manager
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/eraser/Eraser.Manager/ErasureTarget.cs

    r2052 r2132  
    191191    } 
    192192 
    193     public class ErasureTargetRegistrar : Registrar<ErasureTarget> 
     193    public class ErasureTargetRegistrar : FactoryRegistrar<ErasureTarget> 
    194194    { 
    195195    } 
  • trunk/eraser/Eraser.Manager/IRegistrar.cs

    r1802 r2132  
    2424using System.Collections.Generic; 
    2525using System.Text; 
     26using System.Reflection; 
    2627 
    2728namespace Eraser.Manager 
     
    8081 
    8182    /// <summary> 
    82     /// Provides a simple Registrar implementation. 
     83    /// Provides a simple Registrar implementation. This registrar maintains one 
     84    /// instance of each registered member for the entire application. 
    8385    /// </summary> 
    8486    /// <typeparam name="T">The registerable's type.</typeparam> 
     
    268270        private Dictionary<Guid, T> Dictionary = new Dictionary<Guid, T>(); 
    269271    } 
     272 
     273    /// <summary> 
     274    /// Provides a simple Registrar implementation. This registrar creates new instances 
     275    /// every time it is enumerated (copy on read) 
     276    /// </summary> 
     277    /// <typeparam name="T">The registerable's type.</typeparam> 
     278    public class FactoryRegistrar<T> : IRegistrar<T> where T : IRegisterable 
     279    { 
     280        #region IList<T> Members 
     281 
     282        public int IndexOf(T item) 
     283        { 
     284            lock (List) 
     285                return List.IndexOf(item.GetType().GetConstructor(Type.EmptyTypes)); 
     286        } 
     287 
     288        public void Insert(int index, T item) 
     289        { 
     290            //Get the constructor for the class. 
     291            ConstructorInfo ctor = item.GetType().GetConstructor(Type.EmptyTypes); 
     292 
     293            //Check for a valid constructor. 
     294            if (ctor == null) 
     295                throw new ArgumentException("Registered FactoryRegistrar items must contain " + 
     296                    "a parameterless constructor that is called whenever clients request " + 
     297                    "for an instance of the method."); 
     298 
     299            lock (List) 
     300            { 
     301                List.Insert(index, ctor); 
     302                Dictionary.Add(item.Guid, ctor); 
     303            } 
     304 
     305            if (Registered != null) 
     306                Registered(item, EventArgs.Empty); 
     307        } 
     308 
     309        public void RemoveAt(int index) 
     310        { 
     311            ConstructorInfo value = null; 
     312            lock (List) 
     313            { 
     314                value = List[index]; 
     315                List.RemoveAt(index); 
     316                Dictionary.Remove(value.DeclaringType.GUID); 
     317            } 
     318 
     319            if (Unregistered != null) 
     320                Unregistered(value.Invoke(new object[0]), EventArgs.Empty); 
     321        } 
     322 
     323        public T this[int index] 
     324        { 
     325            get 
     326            { 
     327                lock (List) 
     328                    return (T)List[index].Invoke(new object[0]); 
     329            } 
     330            set 
     331            { 
     332                lock (List) 
     333                    List[index] = value.GetType().GetConstructor(Type.EmptyTypes); 
     334            } 
     335        } 
     336 
     337        #endregion 
     338 
     339        #region ICollection<T> Members 
     340 
     341        /// <remarks>If the registerable object is added twice, the second registration 
     342        /// is ignored.</remarks> 
     343        public void Add(T item) 
     344        { 
     345            Insert(Count, item); 
     346        } 
     347 
     348        public void Clear() 
     349        { 
     350            lock (List) 
     351            { 
     352                if (Unregistered != null) 
     353                    List.ForEach(item => Unregistered(item, EventArgs.Empty)); 
     354                List.Clear(); 
     355                Dictionary.Clear(); 
     356            } 
     357        } 
     358 
     359        public bool Contains(T item) 
     360        { 
     361            lock (List) 
     362                return List.Contains(item.GetType().GetConstructor(Type.EmptyTypes)); 
     363        } 
     364 
     365        public void CopyTo(T[] array, int arrayIndex) 
     366        { 
     367            lock (List) 
     368            { 
     369                for (int i = arrayIndex, j = 0; i < array.Length; ++i, ++j) 
     370                { 
     371                    array[i] = (T)List[j].Invoke(new object[0]); 
     372                } 
     373            } 
     374        } 
     375 
     376        public int Count 
     377        { 
     378            get 
     379            { 
     380                lock (List) 
     381                    return List.Count; 
     382            } 
     383        } 
     384 
     385        public bool IsReadOnly 
     386        { 
     387            get { return false; } 
     388        } 
     389 
     390        public bool Remove(T item) 
     391        { 
     392            bool result = false; 
     393            lock (List) 
     394            { 
     395                result = List.Remove(item.GetType().GetConstructor(Type.EmptyTypes)); 
     396                Dictionary.Remove(item.Guid); 
     397            } 
     398 
     399            if (result && Unregistered != null) 
     400                Unregistered(item, EventArgs.Empty); 
     401            return result; 
     402        } 
     403 
     404        #endregion 
     405 
     406        #region IEnumerable<T> Members 
     407 
     408        public IEnumerator<T> GetEnumerator() 
     409        { 
     410            return new Enumerator(List.GetEnumerator()); 
     411        } 
     412 
     413        #endregion 
     414 
     415        #region IEnumerable Members 
     416 
     417        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() 
     418        { 
     419            return List.GetEnumerator(); 
     420        } 
     421 
     422        #endregion 
     423 
     424        #region IRegistrar<T> Members 
     425 
     426        public T this[Guid key] 
     427        { 
     428            get 
     429            { 
     430                lock (List) 
     431                    return (T)Dictionary[key].Invoke(new object[0]); 
     432            } 
     433        } 
     434 
     435        public bool Contains(Guid key) 
     436        { 
     437            lock (List) 
     438                return Dictionary.ContainsKey(key); 
     439        } 
     440 
     441        public bool Remove(Guid key) 
     442        { 
     443            ConstructorInfo ctor = Dictionary[key]; 
     444            bool result = false; 
     445            lock (List) 
     446            { 
     447                result = Dictionary.Remove(key); 
     448                result = result && List.Remove(ctor); 
     449            } 
     450 
     451            if (result && Unregistered != null) 
     452                Unregistered(ctor.Invoke(new object[0]), EventArgs.Empty); 
     453            return result; 
     454        } 
     455 
     456        public EventHandler<EventArgs> Registered { get; set; } 
     457 
     458        public EventHandler<EventArgs> Unregistered { get; set; } 
     459 
     460        #endregion 
     461 
     462        private struct Enumerator : IEnumerator<T> 
     463        { 
     464            public Enumerator(List<ConstructorInfo>.Enumerator enumerator) 
     465            { 
     466                Enum = enumerator; 
     467            } 
     468 
     469            #region IEnumerator<T> Members 
     470 
     471            public T Current 
     472            { 
     473                get { return (T)Enum.Current.Invoke(new object[0]); } 
     474            } 
     475 
     476            #endregion 
     477 
     478            #region IDisposable Members 
     479 
     480            public void Dispose() 
     481            { 
     482                Enum.Dispose(); 
     483            } 
     484 
     485            #endregion 
     486 
     487            #region IEnumerator Members 
     488 
     489            object System.Collections.IEnumerator.Current 
     490            { 
     491                get { return this.Current; } 
     492            } 
     493 
     494            public bool MoveNext() 
     495            { 
     496                return Enum.MoveNext(); 
     497            } 
     498 
     499            public void Reset() 
     500            { 
     501                ((System.Collections.IEnumerator)Enum).Reset(); 
     502            } 
     503 
     504            #endregion 
     505 
     506            private List<ConstructorInfo>.Enumerator Enum; 
     507        } 
     508 
     509        /// <summary> 
     510        /// The backing list for this object. 
     511        /// </summary> 
     512        private List<ConstructorInfo> List = new List<ConstructorInfo>(); 
     513 
     514        /// <summary> 
     515        /// The backing dictionary for this object. 
     516        /// </summary> 
     517        private Dictionary<Guid, ConstructorInfo> Dictionary = 
     518            new Dictionary<Guid, ConstructorInfo>(); 
     519    } 
    270520} 
Note: See TracChangeset for help on using the changeset viewer.