Skip to content

Commit 3c516c2

Browse files
Merge pull request #1 from johelvisguzman/feature/spec
Introduced specification
2 parents 3cd557d + 356fbe9 commit 3c516c2

File tree

16 files changed

+865
-24
lines changed

16 files changed

+865
-24
lines changed

DotNetToolkit.Repository.sln

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{DD273D5E-6D6
77
EndProject
88
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetToolkit.Repository", "src\DotNetToolkit.Repository\DotNetToolkit.Repository.csproj", "{76BC5AB7-1198-4C99-B2C3-3B734931F8EE}"
99
EndProject
10+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{DAB3DD1E-AD99-46C9-AC42-07E2F03D5A06}"
11+
EndProject
12+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DotNetToolkit.Repository.Test", "test\DotNetToolkit.Repository.Test\DotNetToolkit.Repository.Test.csproj", "{EAE7B507-D908-4650-A301-C3341F005A51}"
13+
EndProject
1014
Global
1115
GlobalSection(SolutionConfigurationPlatforms) = preSolution
1216
Debug|Any CPU = Debug|Any CPU
@@ -17,12 +21,17 @@ Global
1721
{76BC5AB7-1198-4C99-B2C3-3B734931F8EE}.Debug|Any CPU.Build.0 = Debug|Any CPU
1822
{76BC5AB7-1198-4C99-B2C3-3B734931F8EE}.Release|Any CPU.ActiveCfg = Release|Any CPU
1923
{76BC5AB7-1198-4C99-B2C3-3B734931F8EE}.Release|Any CPU.Build.0 = Release|Any CPU
24+
{EAE7B507-D908-4650-A301-C3341F005A51}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
25+
{EAE7B507-D908-4650-A301-C3341F005A51}.Debug|Any CPU.Build.0 = Debug|Any CPU
26+
{EAE7B507-D908-4650-A301-C3341F005A51}.Release|Any CPU.ActiveCfg = Release|Any CPU
27+
{EAE7B507-D908-4650-A301-C3341F005A51}.Release|Any CPU.Build.0 = Release|Any CPU
2028
EndGlobalSection
2129
GlobalSection(SolutionProperties) = preSolution
2230
HideSolutionNode = FALSE
2331
EndGlobalSection
2432
GlobalSection(NestedProjects) = preSolution
2533
{76BC5AB7-1198-4C99-B2C3-3B734931F8EE} = {DD273D5E-6D6C-41FA-A0C8-646CC53C4DC3}
34+
{EAE7B507-D908-4650-A301-C3341F005A51} = {DAB3DD1E-AD99-46C9-AC42-07E2F03D5A06}
2635
EndGlobalSection
2736
GlobalSection(ExtensibilityGlobals) = postSolution
2837
SolutionGuid = {96973E0C-81D1-42DE-9F78-7103241B4E07}

appveyor.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,5 +45,11 @@ build:
4545
after_build:
4646
- dotnet pack .\src\DotNetToolkit.Repository\DotNetToolkit.Repository.csproj --configuration Release
4747

48+
#---------------------------------#
49+
# tests configuration #
50+
#---------------------------------#
51+
test_script:
52+
- dotnet test .\test\DotNetToolkit.Repository.Test\DotNetToolkit.Repository.Test.csproj --configuration Release
53+
4854
artifacts:
4955
- path: '**\DotNetToolkit.Repository.*.nupkg' # find all NuGet packages recursively
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
namespace DotNetToolkit.Repository.FetchStrategies
2+
{
3+
using System;
4+
using System.Collections.Generic;
5+
using System.Linq.Expressions;
6+
7+
/// <summary>
8+
/// An implementation of <see cref="IFetchStrategy{T}" />.
9+
/// </summary>
10+
public class FetchStrategy<T> : IFetchStrategy<T>
11+
{
12+
#region Fields
13+
14+
private readonly IList<string> _properties;
15+
16+
#endregion
17+
18+
#region Constructors
19+
20+
/// <summary>
21+
/// Initializes a new instance of the <see cref="FetchStrategy{T}" /> class.
22+
/// </summary>
23+
public FetchStrategy()
24+
{
25+
_properties = new List<string>();
26+
}
27+
28+
#endregion
29+
30+
#region IFetchStrategy<T> Members
31+
32+
/// <summary>
33+
/// Gets the collection of related objects to include in the query results.
34+
/// </summary>
35+
public IEnumerable<string> IncludePaths
36+
{
37+
get { return _properties; }
38+
}
39+
40+
/// <summary>
41+
/// Specifies the related objects to include in the query results.
42+
/// </summary>
43+
/// <param name="path">A lambda expression representing the path to include.</param>
44+
/// <returns>A new <see cref="IFetchStrategy{T}" /> with the defined query path.</returns>
45+
public IFetchStrategy<T> Include(Expression<Func<T, object>> path)
46+
{
47+
return Include(path.ToIncludeString());
48+
}
49+
50+
/// <summary>
51+
/// Specifies the related objects to include in the query results.
52+
/// </summary>
53+
/// <param name="path">The dot-separated list of related objects to return in the query results.</param>
54+
/// <returns>A new <see cref="IFetchStrategy{T}" /> with the defined query path.</returns>
55+
public IFetchStrategy<T> Include(string path)
56+
{
57+
_properties.Add(path);
58+
return this;
59+
}
60+
61+
#endregion
62+
}
63+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
namespace DotNetToolkit.Repository.FetchStrategies
2+
{
3+
using Helpers;
4+
using System;
5+
using System.Collections.Generic;
6+
using System.Linq.Expressions;
7+
using System.Reflection;
8+
using System.Text;
9+
10+
// https://github.com/SharpRepository/SharpRepository/tree/master/SharpRepository.Repository/FetchStrategies/FetchStrategyExtensions.cs
11+
internal static class FetchStrategyExtensions
12+
{
13+
/// <summary>
14+
/// Evaluates the Linq expression and returns the name of the property or the multiple level deep string representation of the Expression (i.e. prop.Collection.Property).
15+
/// </summary>
16+
/// <typeparam name="T">Type being evaluated</typeparam>
17+
/// <param name="selector">Name of the property per the Linq expression</param>
18+
/// <returns></returns>
19+
public static string ToIncludeString<T>(this Expression<Func<T, object>> selector)
20+
{
21+
// Retrieve member path:
22+
var members = new List<PropertyInfo>();
23+
ExpressionHelper.CollectRelationalMembers(selector, members);
24+
25+
// Build string path:
26+
var sb = new StringBuilder();
27+
var separator = "";
28+
foreach (var member in members)
29+
{
30+
sb.Append(separator);
31+
sb.Append(member.Name);
32+
separator = ".";
33+
}
34+
35+
// return concatenated string
36+
return sb.ToString();
37+
}
38+
}
39+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
namespace DotNetToolkit.Repository.FetchStrategies
2+
{
3+
using System;
4+
using System.Collections.Generic;
5+
using System.Linq.Expressions;
6+
7+
/// <summary>
8+
/// An abstraction which defines the child objects that should be retrieved when loading the entity.
9+
/// </summary>
10+
/// <typeparam name="T">The type of the entity.</typeparam>
11+
public interface IFetchStrategy<T>
12+
{
13+
/// <summary>
14+
/// Gets the collection of related objects to include in the query results.
15+
/// </summary>
16+
IEnumerable<string> IncludePaths { get; }
17+
18+
/// <summary>
19+
/// Specifies the related objects to include in the query results.
20+
/// </summary>
21+
/// <param name="path">A lambda expression representing the path to include.</param>
22+
/// <returns>A new <see cref="IFetchStrategy{T}" /> with the defined query path.</returns>
23+
IFetchStrategy<T> Include(Expression<Func<T, object>> path);
24+
25+
/// <summary>
26+
/// Specifies the related objects to include in the query results.
27+
/// </summary>
28+
/// <param name="path">The dot-separated list of related objects to return in the query results.</param>
29+
/// <returns>A new <see cref="IFetchStrategy{T}" /> with the defined query path.</returns>
30+
IFetchStrategy<T> Include(string path);
31+
}
32+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
namespace DotNetToolkit.Repository.Helpers
2+
{
3+
using System;
4+
using System.Collections.Generic;
5+
using System.Linq.Expressions;
6+
using System.Reflection;
7+
8+
// https://github.com/SharpRepository/SharpRepository/tree/master/SharpRepository.Repository/Helpers/ExpressionHelper.cs
9+
internal static class ExpressionHelper
10+
{
11+
internal static void CollectRelationalMembers(Expression exp, IList<PropertyInfo> members)
12+
{
13+
switch (exp.NodeType)
14+
{
15+
case ExpressionType.Lambda:
16+
CollectRelationalMembers(((LambdaExpression)exp).Body, members);
17+
break;
18+
case ExpressionType.MemberAccess:
19+
var mexp = (MemberExpression)exp;
20+
CollectRelationalMembers(mexp.Expression, members);
21+
members.Add((PropertyInfo)mexp.Member);
22+
23+
break;
24+
case ExpressionType.Call:
25+
var cexp = (MethodCallExpression)exp;
26+
27+
if (cexp.Method.IsStatic == false)
28+
throw new InvalidOperationException("Invalid type of expression.");
29+
30+
foreach (var arg in cexp.Arguments)
31+
CollectRelationalMembers(arg, members);
32+
33+
break;
34+
case ExpressionType.Parameter:
35+
return;
36+
default:
37+
throw new InvalidOperationException("Invalid type of expression.");
38+
}
39+
}
40+
}
41+
}

src/DotNetToolkit.Repository/IRepository.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
/// </summary>
88
/// <typeparam name="TEntity">The type of the entity.</typeparam>
99
/// <typeparam name="TKey">The type of the primary key.</typeparam>
10-
public interface IRepository<TEntity, in TKey> : ICanAdd<TEntity>, ICanUpdate<TEntity>, ICanDelete<TEntity, TKey>, ICanGet<TEntity, TKey>, ICanFind<TEntity, TKey>
10+
public interface IRepository<TEntity, in TKey> : ICanAdd<TEntity>, ICanUpdate<TEntity>, ICanDelete<TEntity, TKey>, ICanGet<TEntity, TKey>, ICanFind<TEntity>
1111
where TEntity : class
1212
{
1313
}

0 commit comments

Comments
 (0)