Line data Source code
1 : #region Copyright
2 : // // -----------------------------------------------------------------------
3 : // // <copyright company="Chinchilla Software Limited">
4 : // // Copyright Chinchilla Software Limited. All rights reserved.
5 : // // </copyright>
6 : // // -----------------------------------------------------------------------
7 : #endregion
8 :
9 : using System;
10 : using System.Collections;
11 : using System.Collections.Concurrent;
12 : using System.Collections.Generic;
13 : using System.Linq;
14 : using Cqrs.Entities;
15 :
16 : namespace Cqrs.Repositories
17 : {
18 : /// <summary>
19 : /// Uses a static <see cref="ConcurrentDictionary{TKey,TValue}"/> to store data accessible by all threads.
20 : /// </summary>
21 : public class InMemoryDatabase
22 1 : {
23 : private static IDictionary<Type, object> Database { get; set; }
24 :
25 : static InMemoryDatabase()
26 : {
27 : Database = new ConcurrentDictionary<Type, object>();
28 : }
29 :
30 : /// <summary>
31 : /// Gets all instances of the specific <typeparamref name="TEntity"/> grouped by their ID.
32 : /// </summary>
33 1 : public IDictionary<Guid, TEntity> Get<TEntity>()
34 : where TEntity : Entity
35 : {
36 : IDictionary<Guid, TEntity> result;
37 : if (!Database.ContainsKey(typeof(TEntity)))
38 : {
39 : result = new Dictionary<Guid, TEntity>();
40 : Database.Add(typeof(TEntity), result);
41 : }
42 : else
43 : {
44 : object rawResult = Database[typeof(TEntity)];
45 : result = (IDictionary<Guid, TEntity>)rawResult;
46 : }
47 : return result;
48 : }
49 :
50 : /// <summary>
51 : /// Gets all instances of the specific <typeparamref name="TEntity"/>
52 : /// </summary>
53 1 : public IList<TEntity> GetAll<TEntity>()
54 : where TEntity : Entity
55 : {
56 : IDictionary<Guid, TEntity> result = Get<TEntity>();
57 :
58 : return new CollectionWrapper<TEntity>(result);
59 : }
60 :
61 : class CollectionWrapper<TEntity> : IList<TEntity>
62 : where TEntity : Entity
63 : {
64 : IDictionary<Guid, TEntity> Source { get; set; }
65 :
66 : /// <summary>
67 : /// Instantiates a new instance of <see cref="CollectionWrapper{TEntity}"/>
68 : /// </summary>
69 1 : public CollectionWrapper(IDictionary<Guid, TEntity> source)
70 : {
71 : Source = source;
72 : }
73 :
74 : #region Implementation of IEnumerable
75 :
76 : /// <summary>
77 : /// Returns an enumerator that iterates through the collection.
78 : /// </summary>
79 : /// <returns>
80 : /// A <see cref="T:System.Collections.Generic.IEnumerator`1"/> that can be used to iterate through the collection.
81 : /// </returns>
82 1 : public IEnumerator<TEntity> GetEnumerator()
83 : {
84 : return Source.Values.GetEnumerator();
85 : }
86 :
87 : /// <summary>
88 : /// Returns an enumerator that iterates through a collection.
89 : /// </summary>
90 : /// <returns>
91 : /// An <see cref="T:System.Collections.IEnumerator"/> object that can be used to iterate through the collection.
92 : /// </returns>
93 : IEnumerator IEnumerable.GetEnumerator()
94 : {
95 : return GetEnumerator();
96 : }
97 :
98 : #endregion
99 :
100 : #region Implementation of ICollection<T>
101 :
102 : /// <summary>
103 : /// Adds an item to the <see cref="T:System.Collections.Generic.ICollection`1"/>.
104 : /// </summary>
105 : /// <param name="item">The object to add to the <see cref="T:System.Collections.Generic.ICollection`1"/>.</param><exception cref="T:System.NotSupportedException">The <see cref="T:System.Collections.Generic.ICollection`1"/> is read-only.</exception>
106 1 : public void Add(TEntity item)
107 : {
108 : Source.Add(item.Rsn, item);
109 : }
110 :
111 : /// <summary>
112 : /// Removes all items from the <see cref="T:System.Collections.Generic.ICollection`1"/>.
113 : /// </summary>
114 : /// <exception cref="T:System.NotSupportedException">The <see cref="T:System.Collections.Generic.ICollection`1"/> is read-only. </exception>
115 1 : public void Clear()
116 : {
117 : Source.Clear();
118 : }
119 :
120 : /// <summary>
121 : /// Determines whether the <see cref="T:System.Collections.Generic.ICollection`1"/> contains a specific value.
122 : /// </summary>
123 : /// <returns>
124 : /// true if <paramref name="item"/> is found in the <see cref="T:System.Collections.Generic.ICollection`1"/>; otherwise, false.
125 : /// </returns>
126 : /// <param name="item">The object to locate in the <see cref="T:System.Collections.Generic.ICollection`1"/>.</param>
127 1 : public bool Contains(TEntity item)
128 : {
129 : return Source.Values.Contains(item);
130 : }
131 :
132 : /// <summary>
133 : /// Copies the elements of the <see cref="T:System.Collections.Generic.ICollection`1"/> to an <see cref="T:System.Array"/>, starting at a particular <see cref="T:System.Array"/> index.
134 : /// </summary>
135 : /// <param name="array">The one-dimensional <see cref="T:System.Array"/> that is the destination of the elements copied from <see cref="T:System.Collections.Generic.ICollection`1"/>. The <see cref="T:System.Array"/> must have zero-based indexing.</param>
136 : /// <param name="arrayIndex">The zero-based index in <paramref name="array"/> at which copying begins.</param>
137 : /// <exception cref="T:System.ArgumentNullException"><paramref name="array"/> is null.</exception>
138 : /// <exception cref="T:System.ArgumentOutOfRangeException"><paramref name="arrayIndex"/> is less than 0.</exception>
139 : /// <exception cref="T:System.ArgumentException"><paramref name="array"/> is multidimensional.-or-The number of elements in the source <see cref="T:System.Collections.Generic.ICollection`1"/> is greater than the available space from <paramref name="arrayIndex"/> to the end of the destination <paramref name="array"/>.-or-Type <typeparamref name="TEntity"/> cannot be cast automatically to the type of the destination <paramref name="array"/>.</exception>
140 1 : public void CopyTo(TEntity[] array, int arrayIndex)
141 : {
142 : Source.Values.CopyTo(array, arrayIndex);
143 : }
144 :
145 : /// <summary>
146 : /// Removes the first occurrence of a specific object from the <see cref="T:System.Collections.Generic.ICollection`1"/>.
147 : /// </summary>
148 : /// <returns>
149 : /// true if <paramref name="item"/> was successfully removed from the <see cref="T:System.Collections.Generic.ICollection`1"/>; otherwise, false. This method also returns false if <paramref name="item"/> is not found in the original <see cref="T:System.Collections.Generic.ICollection`1"/>.
150 : /// </returns>
151 : /// <param name="item">The object to remove from the <see cref="T:System.Collections.Generic.ICollection`1"/>.</param><exception cref="T:System.NotSupportedException">The <see cref="T:System.Collections.Generic.ICollection`1"/> is read-only.</exception>
152 1 : public bool Remove(TEntity item)
153 : {
154 : return Source.Remove(item.Rsn);
155 : }
156 :
157 : /// <summary>
158 : /// Gets the number of elements contained in the <see cref="T:System.Collections.Generic.ICollection`1"/>.
159 : /// </summary>
160 : /// <returns>
161 : /// The number of elements contained in the <see cref="T:System.Collections.Generic.ICollection`1"/>.
162 : /// </returns>
163 : public int Count
164 : {
165 : get { return Source.Count; }
166 : }
167 :
168 : /// <summary>
169 : /// Gets a value indicating whether the <see cref="T:System.Collections.Generic.ICollection`1"/> is read-only.
170 : /// </summary>
171 : /// <returns>
172 : /// true if the <see cref="T:System.Collections.Generic.ICollection`1"/> is read-only; otherwise, false.
173 : /// </returns>
174 : public bool IsReadOnly
175 : {
176 : get { return Source.IsReadOnly; }
177 : }
178 :
179 : #endregion
180 :
181 : #region Implementation of IList<T>
182 :
183 : /// <summary>
184 : /// Determines the index of a specific item in the <see cref="T:System.Collections.Generic.IList`1"/>.
185 : /// </summary>
186 : /// <returns>
187 : /// The index of <paramref name="item"/> if found in the list; otherwise, -1.
188 : /// </returns>
189 : /// <param name="item">The object to locate in the <see cref="T:System.Collections.Generic.IList`1"/>.</param>
190 1 : public int IndexOf(TEntity item)
191 : {
192 : return Source.Values.ToList().IndexOf(item);
193 : }
194 :
195 : /// <summary>
196 : /// Inserts an item to the <see cref="T:System.Collections.Generic.IList`1"/> at the specified index.
197 : /// </summary>
198 : /// <param name="index">The zero-based index at which <paramref name="item"/> should be inserted.</param><param name="item">The object to insert into the <see cref="T:System.Collections.Generic.IList`1"/>.</param><exception cref="T:System.ArgumentOutOfRangeException"><paramref name="index"/> is not a valid index in the <see cref="T:System.Collections.Generic.IList`1"/>.</exception><exception cref="T:System.NotSupportedException">The <see cref="T:System.Collections.Generic.IList`1"/> is read-only.</exception>
199 1 : public void Insert(int index, TEntity item)
200 : {
201 : Add(item);
202 : }
203 :
204 : /// <summary>
205 : /// Removes the <see cref="T:System.Collections.Generic.IList`1"/> item at the specified index.
206 : /// </summary>
207 : /// <param name="index">The zero-based index of the item to remove.</param><exception cref="T:System.ArgumentOutOfRangeException"><paramref name="index"/> is not a valid index in the <see cref="T:System.Collections.Generic.IList`1"/>.</exception><exception cref="T:System.NotSupportedException">The <see cref="T:System.Collections.Generic.IList`1"/> is read-only.</exception>
208 1 : public void RemoveAt(int index)
209 : {
210 : Remove(Source.Values.ToList()[index]);
211 : }
212 :
213 : /// <summary>
214 : /// Gets or sets the element at the specified index.
215 : /// </summary>
216 : /// <returns>
217 : /// The element at the specified index.
218 : /// </returns>
219 : /// <param name="index">The zero-based index of the element to get or set.</param><exception cref="T:System.ArgumentOutOfRangeException"><paramref name="index"/> is not a valid index in the <see cref="T:System.Collections.Generic.IList`1"/>.</exception><exception cref="T:System.NotSupportedException">The property is set and the <see cref="T:System.Collections.Generic.IList`1"/> is read-only.</exception>
220 : public TEntity this[int index]
221 : {
222 : get { return Source.Values.ToList()[index]; }
223 : set { Source[this[index].Rsn] = value; }
224 : }
225 :
226 : #endregion
227 : }
228 : }
229 : }
|