Skip to content

Commit 38f19eb

Browse files
Merge pull request #32 from johelvisguzman/dev
Merge branch 'dev' into master for v2.1.0
2 parents 6f0dea9 + e8b9d25 commit 38f19eb

38 files changed

+4028
-704
lines changed

DotNetToolkit.Repository.sln

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22
Microsoft Visual Studio Solution File, Format Version 12.00
33
# Visual Studio 15
4-
VisualStudioVersion = 15.0.27130.2003
4+
VisualStudioVersion = 15.0.27004.2006
55
MinimumVisualStudioVersion = 10.0.40219.1
66
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{DD273D5E-6D6C-41FA-A0C8-646CC53C4DC3}"
77
EndProject
@@ -17,7 +17,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetToolkit.Repository.In
1717
EndProject
1818
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetToolkit.Repository.InMemory", "src\DotNetToolkit.Repository.InMemory\DotNetToolkit.Repository.InMemory.csproj", "{715D2F11-3AAF-476E-9A6A-DCA6DEBD377E}"
1919
EndProject
20-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DotNetToolkit.Repository.EntityFrameworkCore", "src\DotNetToolkit.Repository.EntityFrameworkCore\DotNetToolkit.Repository.EntityFrameworkCore.csproj", "{0A9D9AA4-F01C-470F-AD5B-5A81EA7A398D}"
20+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetToolkit.Repository.EntityFrameworkCore", "src\DotNetToolkit.Repository.EntityFrameworkCore\DotNetToolkit.Repository.EntityFrameworkCore.csproj", "{0A9D9AA4-F01C-470F-AD5B-5A81EA7A398D}"
21+
EndProject
22+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetToolkit.Repository.Json", "src\DotNetToolkit.Repository.Json\DotNetToolkit.Repository.Json.csproj", "{B71EA207-390A-4AB0-BFC8-44BA124FC35B}"
23+
EndProject
24+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DotNetToolkit.Repository.Xml", "src\DotNetToolkit.Repository.Xml\DotNetToolkit.Repository.Xml.csproj", "{BB858B77-5CE8-4301-9FB6-343FFF5B7E63}"
2125
EndProject
2226
Global
2327
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -49,6 +53,14 @@ Global
4953
{0A9D9AA4-F01C-470F-AD5B-5A81EA7A398D}.Debug|Any CPU.Build.0 = Debug|Any CPU
5054
{0A9D9AA4-F01C-470F-AD5B-5A81EA7A398D}.Release|Any CPU.ActiveCfg = Release|Any CPU
5155
{0A9D9AA4-F01C-470F-AD5B-5A81EA7A398D}.Release|Any CPU.Build.0 = Release|Any CPU
56+
{B71EA207-390A-4AB0-BFC8-44BA124FC35B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
57+
{B71EA207-390A-4AB0-BFC8-44BA124FC35B}.Debug|Any CPU.Build.0 = Debug|Any CPU
58+
{B71EA207-390A-4AB0-BFC8-44BA124FC35B}.Release|Any CPU.ActiveCfg = Release|Any CPU
59+
{B71EA207-390A-4AB0-BFC8-44BA124FC35B}.Release|Any CPU.Build.0 = Release|Any CPU
60+
{BB858B77-5CE8-4301-9FB6-343FFF5B7E63}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
61+
{BB858B77-5CE8-4301-9FB6-343FFF5B7E63}.Debug|Any CPU.Build.0 = Debug|Any CPU
62+
{BB858B77-5CE8-4301-9FB6-343FFF5B7E63}.Release|Any CPU.ActiveCfg = Release|Any CPU
63+
{BB858B77-5CE8-4301-9FB6-343FFF5B7E63}.Release|Any CPU.Build.0 = Release|Any CPU
5264
EndGlobalSection
5365
GlobalSection(SolutionProperties) = preSolution
5466
HideSolutionNode = FALSE
@@ -60,6 +72,8 @@ Global
6072
{2F99B66F-A347-4E8D-8ACA-5A34246A1FA6} = {DAB3DD1E-AD99-46C9-AC42-07E2F03D5A06}
6173
{715D2F11-3AAF-476E-9A6A-DCA6DEBD377E} = {DD273D5E-6D6C-41FA-A0C8-646CC53C4DC3}
6274
{0A9D9AA4-F01C-470F-AD5B-5A81EA7A398D} = {DD273D5E-6D6C-41FA-A0C8-646CC53C4DC3}
75+
{B71EA207-390A-4AB0-BFC8-44BA124FC35B} = {DD273D5E-6D6C-41FA-A0C8-646CC53C4DC3}
76+
{BB858B77-5CE8-4301-9FB6-343FFF5B7E63} = {DD273D5E-6D6C-41FA-A0C8-646CC53C4DC3}
6377
EndGlobalSection
6478
GlobalSection(ExtensibilityGlobals) = postSolution
6579
SolutionGuid = {96973E0C-81D1-42DE-9F78-7103241B4E07}

appveyor.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ after_build:
4848
- dotnet pack .\src\DotNetToolkit.Repository.InMemory\DotNetToolkit.Repository.InMemory.csproj --configuration Release
4949
- dotnet pack .\src\DotNetToolkit.Repository.EntityFramework\DotNetToolkit.Repository.EntityFramework.csproj --configuration Release
5050
- dotnet pack .\src\DotNetToolkit.Repository.EntityFrameworkCore\DotNetToolkit.Repository.EntityFrameworkCore.csproj --configuration Release
51+
- dotnet pack .\src\DotNetToolkit.Repository.Json\DotNetToolkit.Repository.Json.csproj --configuration Release
52+
- dotnet pack .\src\DotNetToolkit.Repository.Xml\DotNetToolkit.Repository.Xml.csproj --configuration Release
5153

5254
#---------------------------------#
5355
# tests configuration #

src/DotNetToolkit.Repository.EntityFramework/EfRepositoryBase.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,17 @@ public override void Dispose()
223223
return predicate == null ? GetQuery().AnyAsync(cancellationToken) : GetQuery().AnyAsync(predicate, cancellationToken);
224224
}
225225

226+
/// <summary>
227+
/// A protected asynchronous overridable method for getting a new <see cref="IDictionary{TDictionaryKey, TElement}" /> according to the specified <paramref name="keySelector" />, an element selector.
228+
/// </summary>
229+
protected override Task<Dictionary<TDictionaryKey, TElement>> GetDictionaryAsync<TDictionaryKey, TElement>(ISpecification<TEntity> criteria, Func<TEntity, TDictionaryKey> keySelector, Func<TEntity, TElement> elementSelector, IQueryOptions<TEntity> options, CancellationToken cancellationToken = new CancellationToken())
230+
{
231+
if (keySelector == null)
232+
throw new ArgumentNullException(nameof(keySelector));
233+
234+
return GetQuery(criteria, options).ToDictionaryAsync(keySelector, elementSelector, EqualityComparer<TDictionaryKey>.Default, cancellationToken);
235+
}
236+
226237
#endregion
227238
}
228239
}

src/DotNetToolkit.Repository.EntityFrameworkCore/EfCoreRepositoryBase.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,17 @@ public override void Dispose()
223223
return predicate == null ? GetQuery().AnyAsync(cancellationToken) : GetQuery().AnyAsync(predicate, cancellationToken);
224224
}
225225

226+
/// <summary>
227+
/// A protected asynchronous overridable method for getting a new <see cref="IDictionary{TDictionaryKey, TElement}" /> according to the specified <paramref name="keySelector" />, an element selector.
228+
/// </summary>
229+
protected override Task<Dictionary<TDictionaryKey, TElement>> GetDictionaryAsync<TDictionaryKey, TElement>(ISpecification<TEntity> criteria, Func<TEntity, TDictionaryKey> keySelector, Func<TEntity, TElement> elementSelector, IQueryOptions<TEntity> options, CancellationToken cancellationToken = new CancellationToken())
230+
{
231+
if (keySelector == null)
232+
throw new ArgumentNullException(nameof(keySelector));
233+
234+
return GetQuery(criteria, options).ToDictionaryAsync(keySelector, elementSelector, EqualityComparer<TDictionaryKey>.Default, cancellationToken);
235+
}
236+
226237
#endregion
227238
}
228239
}
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
namespace DotNetToolkit.Repository.InMemory
2+
{
3+
using Properties;
4+
using System;
5+
using System.Collections.Generic;
6+
using System.Globalization;
7+
using System.IO;
8+
using System.Linq;
9+
10+
/// <summary>
11+
/// Represents a file based repository for in-memory operations (for testing purposes).
12+
/// </summary>
13+
public abstract class InMemoryFileBasedRepositoryBase<TEntity, TKey> : InMemoryRepositoryBase<TEntity, TKey> where TEntity : class
14+
{
15+
#region Properties
16+
17+
/// <summary>
18+
/// Gets the file extension.
19+
/// </summary>
20+
protected abstract string FileExtension { get; }
21+
22+
#endregion
23+
24+
#region Constructors
25+
26+
/// <summary>
27+
/// Initializes a new instance of the <see cref="InMemoryFileBasedRepositoryBase{TEntity, TKey}"/> class.
28+
/// </summary>
29+
/// <param name="filePath">The file path.</param>
30+
protected InMemoryFileBasedRepositoryBase(string filePath)
31+
{
32+
OnInitialize(filePath);
33+
}
34+
35+
#endregion
36+
37+
#region Protected Methods
38+
39+
/// <summary>
40+
/// A protected overridable method for loading the entities from the specified stream reader.
41+
/// </summary>
42+
protected abstract IEnumerable<TEntity> OnLoaded(StreamReader reader);
43+
44+
/// <summary>
45+
/// A protected overridable method for saving the entities to the specified stream writer.
46+
/// </summary>
47+
protected abstract void OnSaved(StreamWriter writer, IEnumerable<TEntity> entities);
48+
49+
#endregion
50+
51+
#region Private Methods
52+
53+
private string ValidateFile(string filePath)
54+
{
55+
if (string.IsNullOrEmpty(filePath))
56+
throw new ArgumentException(Resources.ArgumentCannotBeNullOrEmpty, nameof(filePath));
57+
58+
// Ensures we have a valid file
59+
var fileName = filePath;
60+
61+
if (Directory.Exists(filePath))
62+
{
63+
if (!fileName.EndsWith(@"\"))
64+
fileName += @"\";
65+
66+
fileName += $"{GetType().Name}{FileExtension}";
67+
}
68+
else
69+
{
70+
if (string.IsNullOrEmpty(Path.GetExtension(fileName)))
71+
fileName += FileExtension;
72+
73+
if (!Path.GetExtension(fileName).Equals(FileExtension))
74+
throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Resources.InvalidFileExtension, fileName, FileExtension));
75+
76+
if (fileName.IndexOfAny(Path.GetInvalidFileNameChars()) < 0)
77+
throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Resources.InvalidFilePath, fileName));
78+
}
79+
80+
return fileName;
81+
}
82+
83+
private void OnInitialize(string filePath)
84+
{
85+
DatabaseName = ValidateFile(filePath);
86+
87+
// Creates the file if does not exist
88+
if (!File.Exists(DatabaseName))
89+
{
90+
File.Create(DatabaseName).Dispose();
91+
}
92+
// Otherwise, try to get the data from the file
93+
else
94+
{
95+
// Adds the data from the file into memory
96+
using (var stream = new FileStream(DatabaseName, FileMode.Open, FileAccess.Read))
97+
using (var reader = new StreamReader(stream))
98+
{
99+
var entities = OnLoaded(reader);
100+
101+
EnsureDeleted();
102+
103+
foreach (var entity in entities)
104+
{
105+
AddItem(entity);
106+
}
107+
108+
base.SaveChanges();
109+
}
110+
}
111+
}
112+
113+
#endregion
114+
115+
#region Overrides of InMemoryRepositoryBase<TEntity,TKey>
116+
117+
/// <summary>
118+
/// A protected overridable method for saving changes made in the current unit of work in the repository.
119+
/// </summary>
120+
protected override void SaveChanges()
121+
{
122+
using (var stream = new FileStream(DatabaseName, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.Delete))
123+
{
124+
// Saves the data into memory
125+
base.SaveChanges();
126+
127+
// Puts from memory into the file
128+
using (var writer = new StreamWriter(stream))
129+
{
130+
var entities = GetQuery().ToList();
131+
132+
OnSaved(writer, entities);
133+
}
134+
}
135+
}
136+
137+
#endregion
138+
}
139+
}

0 commit comments

Comments
 (0)