@@ -294,6 +294,164 @@ public override string ToString()
294294 }
295295 }
296296
297+
298+ public abstract class CacheCompoundKeyRepositoryBase < T , TKey , TKey2 , TKey3 > : LinqCompoundKeyRepositoryBase < T , TKey , TKey2 , TKey3 > where T : class , new ( )
299+ {
300+ private struct CompoundKey
301+ {
302+ public TKey Key1 { private get ; set ; }
303+ public TKey2 Key2 { private get ; set ; }
304+ public TKey3 Key3 { private get ; set ; }
305+
306+ public override int GetHashCode ( )
307+ {
308+ return Key1 . GetHashCode ( ) ^ Key2 . GetHashCode ( ) ^ Key3 . GetHashCode ( ) ;
309+ }
310+
311+ public override bool Equals ( object obj )
312+ {
313+ if ( obj is CompoundKey )
314+ {
315+ var compositeKey = ( CompoundKey ) obj ;
316+
317+ return Key1 . Equals ( compositeKey . Key1 ) && Key2 . Equals ( compositeKey . Key2 ) && Key3 . Equals ( compositeKey . Key2 ) ;
318+ }
319+
320+ return false ;
321+ }
322+ }
323+
324+ private ConcurrentDictionary < CompoundKey , T > Items
325+ {
326+ get
327+ {
328+ ConcurrentDictionary < CompoundKey , T > items = null ;
329+
330+ if ( ! _cachingProvider . Exists ( _prefix + ".CacheRepository.Items" ) )
331+ {
332+ items = new ConcurrentDictionary < CompoundKey , T > ( ) ;
333+ _cachingProvider . Set ( _prefix + ".CacheRepository.Items" , items ) ;
334+ }
335+ else
336+ {
337+ if ( ! _cachingProvider . Get ( _prefix + ".CacheRepository.Items" , out items ) )
338+ {
339+ items = new ConcurrentDictionary < CompoundKey , T > ( ) ;
340+ }
341+ }
342+
343+ return items ;
344+ }
345+ set
346+ {
347+ _cachingProvider . Set ( _prefix + ".CacheRepository.Items" , value ) ;
348+ }
349+ }
350+
351+ private readonly string _prefix ;
352+ private readonly ICachingProvider _cachingProvider ;
353+
354+ internal CacheCompoundKeyRepositoryBase ( string prefix , ICompoundKeyCachingStrategy < T , TKey , TKey2 , TKey3 > cachingStrategy = null )
355+ : this ( prefix , new InMemoryCachingProvider ( ) , cachingStrategy )
356+ {
357+ }
358+
359+ internal CacheCompoundKeyRepositoryBase ( string prefix , ICachingProvider cachingProvider , ICompoundKeyCachingStrategy < T , TKey , TKey2 , TKey3 > cachingStrategy = null )
360+ : base ( cachingStrategy )
361+ {
362+ _prefix = prefix ;
363+ _cachingProvider = cachingProvider ;
364+ }
365+
366+ protected override IQueryable < T > BaseQuery ( IFetchStrategy < T > fetchStrategy = null )
367+ {
368+ return CloneDictionary ( Items ) . AsQueryable ( ) ;
369+ }
370+
371+ protected override T GetQuery ( TKey key , TKey2 key2 , TKey3 key3 )
372+ {
373+ T result ;
374+ var compoundKey = new CompoundKey { Key1 = key , Key2 = key2 , Key3 = key3 } ;
375+ Items . TryGetValue ( compoundKey , out result ) ;
376+
377+ return result ;
378+ }
379+
380+ private static IEnumerable < T > CloneDictionary ( ConcurrentDictionary < CompoundKey , T > list )
381+ {
382+ // when you Google deep copy of generic list every answer uses either the IClonable interface on the T or having the T be Serializable
383+ // since we can't really put those constraints on T I'm going to do it via reflection
384+
385+ var type = typeof ( T ) ;
386+ var properties = type . GetProperties ( ) ;
387+
388+ var clonedList = new List < T > ( list . Count ) ;
389+
390+ foreach ( var keyValuePair in list )
391+ {
392+ var newItem = new T ( ) ;
393+ foreach ( var propInfo in properties )
394+ {
395+ propInfo . SetValue ( newItem , propInfo . GetValue ( keyValuePair . Value , null ) , null ) ;
396+ }
397+
398+ clonedList . Add ( newItem ) ;
399+ }
400+
401+ return clonedList ;
402+ }
403+
404+ protected override void AddItem ( T entity )
405+ {
406+ TKey key ;
407+ TKey2 key2 ;
408+ TKey3 key3 ;
409+ GetPrimaryKey ( entity , out key , out key2 , out key3 ) ;
410+
411+ var compoundKey = new CompoundKey { Key1 = key , Key2 = key2 , Key3 = key3 } ;
412+ Items [ compoundKey ] = entity ;
413+ }
414+
415+ protected override void DeleteItem ( T entity )
416+ {
417+ TKey key ;
418+ TKey2 key2 ;
419+ TKey3 key3 ;
420+ GetPrimaryKey ( entity , out key , out key2 , out key3 ) ;
421+
422+ T tmp ;
423+ var compoundKey = new CompoundKey { Key1 = key , Key2 = key2 , Key3 = key3 } ;
424+ Items . TryRemove ( compoundKey , out tmp ) ;
425+ }
426+
427+ protected override void UpdateItem ( T entity )
428+ {
429+ TKey key ;
430+ TKey2 key2 ;
431+ TKey3 key3 ;
432+ GetPrimaryKey ( entity , out key , out key2 , out key3 ) ;
433+
434+ var compoundKey = new CompoundKey { Key1 = key , Key2 = key2 , Key3 = key3 } ;
435+ Items [ compoundKey ] = entity ;
436+ }
437+
438+ protected override void SaveChanges ( )
439+ {
440+
441+ }
442+
443+ public override void Dispose ( )
444+ {
445+
446+ }
447+
448+ public override string ToString ( )
449+ {
450+ return "SharpRepository.InMemoryRepository" ;
451+ }
452+ }
453+
454+
297455 public abstract class InMemoryCompoundKeyRepositoryBase < T , TKey , TKey2 , TKey3 > : LinqCompoundKeyRepositoryBase < T , TKey , TKey2 , TKey3 > where T : class , new ( )
298456 {
299457 private struct CompoundKey
0 commit comments