Documentation Coverage Report
Current view: top level - Cqrs/Repositories - Repository.cs Hit Total Coverage
Version: 2.2 Artefacts: 12 12 100.0 %
Date: 2018-08-07 15:04:50

          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.Generic;
      11             : using System.Linq;
      12             : using System.Linq.Expressions;
      13             : using cdmdotnet.Logging;
      14             : using Cqrs.Entities;
      15             : using Cqrs.DataStores;
      16             : using Cqrs.Repositories.Queries;
      17             : 
      18             : namespace Cqrs.Repositories
      19             : {
      20             :         /// <summary>
      21             :         /// Provides basic repository methods for operations with an <see cref="IDataStore{TData}"/>.
      22             :         /// </summary>
      23             :         /// <typeparam name="TQueryStrategy">The <see cref="Type"/> of <see cref="IQueryStrategy"/>.</typeparam>
      24             :         /// <typeparam name="TQueryBuilder">The <see cref="Type"/> of the <see cref="Cqrs.Repositories.Queries.QueryBuilder{TQueryStrategy,TData}"/> that will be used to build queries.</typeparam>
      25             :         /// <typeparam name="TData">The <see cref="Type"/> of data held in storage.</typeparam>
      26             :         public abstract class Repository<TQueryStrategy, TQueryBuilder, TData> : IRepository<TQueryStrategy, TData>
      27             :                 where TQueryStrategy : IQueryStrategy
      28             :                 where TQueryBuilder : QueryBuilder<TQueryStrategy, TData>
      29             :                 where TData : Entity
      30           1 :         {
      31             :                 /// <summary>
      32             :                 /// Gets or sets the <see cref="Func{TResult}"/> that is used to create new instances of <see cref="IDataStore{TData}"/>.
      33             :                 /// </summary>
      34             :                 protected Func<IDataStore<TData>> CreateDataStoreFunction { get; private set; }
      35             : 
      36             :                 /// <summary>
      37             :                 /// Gets or sets the <typeparamref name="TQueryBuilder"/> that will be used to build queries.
      38             :                 /// </summary>
      39             :                 protected TQueryBuilder QueryBuilder { get; private set; }
      40             : 
      41             :                 /// <summary>
      42             :                 /// Gets or sets the <see cref="ITelemetryHelper"/>.
      43             :                 /// </summary>
      44             :                 protected ITelemetryHelper TelemetryHelper { get; set; }
      45             : 
      46             :                 /// <summary>
      47             :                 /// Instantiates a new instance of <see cref="Repository{TQueryStrategy,TQueryBuilder,TData}"/>
      48             :                 /// </summary>
      49           1 :                 protected Repository(Func<IDataStore<TData>> createDataStoreFunction, TQueryBuilder queryBuilder)
      50             :                 {
      51             :                         CreateDataStoreFunction = createDataStoreFunction;
      52             :                         QueryBuilder = queryBuilder;
      53             :                         TelemetryHelper = new NullTelemetryHelper();
      54             :                 }
      55             : 
      56             :                 #region Implementation of IRepository<TData>
      57             : 
      58             :                 /// <summary>
      59             :                 /// Create the newly provided <paramref name="data"/> to storage.
      60             :                 /// </summary>
      61           1 :                 public virtual void Create(TData data)
      62             :                 {
      63             :                         using (var dataStore = CreateDataStoreFunction())
      64             :                                 dataStore.Add(data);
      65             :                 }
      66             : 
      67             :                 /// <summary>
      68             :                 /// Create the newly provided <paramref name="data"/> to storage.
      69             :                 /// </summary>
      70           1 :                 public virtual void Create(IEnumerable<TData> data)
      71             :                 {
      72             :                         using (var dataStore = CreateDataStoreFunction())
      73             :                                 dataStore.Add(data);
      74             :                 }
      75             : 
      76             :                 /// <summary>
      77             :                 /// Builds and executes the provided <paramref name="singleResultQuery"/>.
      78             :                 /// </summary>
      79             :                 /// <param name="singleResultQuery">The <see cref="ISingleResultQuery{TQueryStrategy,TData}"/> to build and execute.</param>
      80             :                 /// <param name="throwExceptionWhenNoQueryResults">If true will throw an <see cref="Exception"/> if no data is found in storage.</param>
      81           1 :                 public virtual ISingleResultQuery<TQueryStrategy, TData> Retrieve(ISingleResultQuery<TQueryStrategy, TData> singleResultQuery, bool throwExceptionWhenNoQueryResults = true)
      82             :                 {
      83             :                         // The .Select(i => i) is necessary due to inheritance
      84             :                         // http://stackoverflow.com/questions/1021274/linq-to-sql-mapping-exception-when-using-abstract-base-classes
      85             :                         IQueryable<TData> query = QueryBuilder.CreateQueryable(singleResultQuery).Select(i => i);
      86             : 
      87             :                         IEnumerable<TData> result = query.AsEnumerable();
      88             :                         int finalResultCount = 0;
      89             :                         TData finalResult = throwExceptionWhenNoQueryResults
      90             :                                 ? result.Single()
      91             :                                 : result.SingleOrDefault();
      92             :                         if (finalResult != null)
      93             :                                 finalResultCount = 1;
      94             : 
      95             :                         try
      96             :                         {
      97             :                                 return new SingleResultQuery<TQueryStrategy, TData>
      98             :                                 {
      99             :                                         QueryStrategy = singleResultQuery.QueryStrategy,
     100             :                                         Result = finalResult
     101             :                                 };
     102             :                         }
     103             :                         finally
     104             :                         {
     105             :                                 TelemetryHelper.TrackMetric(string.Format("Cqrs/Repository/Retrieve/Single/{0}", typeof(TData).Name), finalResultCount);
     106             : 
     107             :                                 // This is disabled until I can figure out a better way to handle disposing these... as it will most likely dispose the data store... and that's not cool.
     108             :                                 /*
     109             :                                 var disposable = result as IDisposable;
     110             :                                 if (disposable != null)
     111             :                                         disposable.Dispose();
     112             :                                 */
     113             :                         }
     114             :                 }
     115             : 
     116             :                 /// <summary>
     117             :                 /// Builds and executes the provided <paramref name="resultQuery"/>.
     118             :                 /// </summary>
     119             :                 /// <param name="resultQuery">The <see cref="ICollectionResultQuery{TQueryStrategy,TData}"/> to build and execute.</param>
     120           1 :                 public virtual ICollectionResultQuery<TQueryStrategy, TData> Retrieve(ICollectionResultQuery<TQueryStrategy, TData> resultQuery)
     121             :                 {
     122             :                         // The .Select(i => i) is necessary due to inheritance
     123             :                         // http://stackoverflow.com/questions/1021274/linq-to-sql-mapping-exception-when-using-abstract-base-classes
     124             :                         IQueryable<TData> result = QueryBuilder.CreateQueryable(resultQuery).Select(i => i);
     125             : 
     126             :                         IList<TData> finalResult = result.ToList();
     127             : 
     128             :                         try
     129             :                         {
     130             :                                 return new CollectionResultQuery<TQueryStrategy, TData>
     131             :                                 {
     132             :                                         QueryStrategy = resultQuery.QueryStrategy,
     133             :                                         Result = finalResult
     134             :                                 };
     135             :                         }
     136             :                         finally
     137             :                         {
     138             :                                 TelemetryHelper.TrackMetric(string.Format("Cqrs/Repository/Retrieve/Collection/{0}", typeof(TData).Name), finalResult.Count);
     139             :                                 // This is disabled until I can figure out a better way to handle disposing these... as it will most likely dispose the data store... and that's not cool.
     140             :                                 /*
     141             :                                 var disposable = result as IDisposable;
     142             :                                 if (disposable != null)
     143             :                                         disposable.Dispose();
     144             :                                 */
     145             :                         }
     146             :                 }
     147             : 
     148             :                 /// <summary>
     149             :                 /// Update the provided <paramref name="data"/> in storage.
     150             :                 /// </summary>
     151           1 :                 public virtual void Update(TData data)
     152             :                 {
     153             :                         using (var dataStore = CreateDataStoreFunction())
     154             :                                 dataStore.Update(data);
     155             :                 }
     156             : 
     157             :                 /// <summary>
     158             :                 /// Will mark the <paramref name="data"/> as logically (or soft).
     159             :                 /// </summary>
     160           1 :                 public virtual void Delete(TData data)
     161             :                 {
     162             :                         using (var dataStore = CreateDataStoreFunction())
     163             :                                 dataStore.Remove(data);
     164             :                 }
     165             : 
     166             :                 /// <summary>
     167             :                 /// Delete all contents (normally by use of a truncate operation) in storage.
     168             :                 /// </summary>
     169           1 :                 public virtual void DeleteAll()
     170             :                 {
     171             :                         using (var dataStore = CreateDataStoreFunction())
     172             :                                 dataStore.RemoveAll();
     173             :                 }
     174             : 
     175             :                 /// <summary>
     176             :                 /// Remove the provided <paramref name="data"/> from storage.
     177             :                 /// </summary>
     178           1 :                 public void Destroy(TData data)
     179             :                 {
     180             :                         using (var dataStore = CreateDataStoreFunction())
     181             :                                 dataStore.Destroy(data);
     182             :                 }
     183             : 
     184             :                 /// <summary>
     185             :                 /// Load the <typeparamref name="TData"/> from storage identified by the provided <paramref name="rsn"/>.
     186             :                 /// </summary>
     187             :                 /// <param name="rsn">The identifier if the <typeparamref name="TData"/> to load.</param>
     188             :                 /// <param name="throwExceptionOnMissingEntity">If true will throw an <see cref="Exception"/> if no data is found in storage.</param>
     189           1 :                 public virtual TData Load(Guid rsn, bool throwExceptionOnMissingEntity = true)
     190             :                 {
     191             :                         using (IDataStore<TData> dataStore = CreateDataStoreFunction())
     192             :                         {
     193             :                                 IEnumerable<TData> query = dataStore
     194             :                                         // The .Select(i => i) is necessary due to inheritance
     195             :                                         // http://stackoverflow.com/questions/1021274/linq-to-sql-mapping-exception-when-using-abstract-base-classes
     196             :                                         .Select(i => i)
     197             :                                         .Where(entity => entity.Rsn == rsn)
     198             :                                         .AsEnumerable();
     199             : 
     200             :                                 int finalResultCount = 0;
     201             :                                 TData result = throwExceptionOnMissingEntity
     202             :                                         ? query.Single()
     203             :                                         : query.SingleOrDefault();
     204             :                                 if (result != null)
     205             :                                         finalResultCount = 1;
     206             : 
     207             :                                 try
     208             :                                 {
     209             :                                         return result;
     210             :                                 }
     211             :                                 finally
     212             :                                 {
     213             :                                         TelemetryHelper.TrackMetric(string.Format("Cqrs/Repository/Load/{0}", typeof(TData).Name), finalResultCount);
     214             :                                 }
     215             :                         }
     216             :                 }
     217             : 
     218             :                 #endregion
     219             : 
     220             :                 /// <summary>
     221             :                 /// Calls <see cref="CreateDataStoreFunction"/> passing the <paramref name="predicate"/>.
     222             :                 /// </summary>
     223             :                 /// <param name="predicate">A function defining a filter if required.</param>
     224           1 :                 protected virtual IQueryable<TData> CreateQueryable(Expression<Func<TData, bool>> predicate)
     225             :                 {
     226             :                         return CreateDataStoreFunction().Where(predicate);
     227             :                 }
     228             :         }
     229             : }

Generated by: LCOV version 1.12