Skip to content

Commit 5e74caa

Browse files
Merge pull request #12 from johelvisguzman/feature/inmemory
Introduced a new in-memory repository
2 parents 76ae5c4 + 5560b4e commit 5e74caa

18 files changed

+1726
-3
lines changed

DotNetToolkit.Repository.sln

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetToolkit.Repository.En
1515
EndProject
1616
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetToolkit.Repository.Integration.Test", "test\DotNetToolkit.Repository.Integration.Test\DotNetToolkit.Repository.Integration.Test.csproj", "{2F99B66F-A347-4E8D-8ACA-5A34246A1FA6}"
1717
EndProject
18+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DotNetToolkit.Repository.InMemory", "src\DotNetToolkit.Repository.InMemory\DotNetToolkit.Repository.InMemory.csproj", "{715D2F11-3AAF-476E-9A6A-DCA6DEBD377E}"
19+
EndProject
1820
Global
1921
GlobalSection(SolutionConfigurationPlatforms) = preSolution
2022
Debug|Any CPU = Debug|Any CPU
@@ -37,6 +39,10 @@ Global
3739
{2F99B66F-A347-4E8D-8ACA-5A34246A1FA6}.Debug|Any CPU.Build.0 = Debug|Any CPU
3840
{2F99B66F-A347-4E8D-8ACA-5A34246A1FA6}.Release|Any CPU.ActiveCfg = Release|Any CPU
3941
{2F99B66F-A347-4E8D-8ACA-5A34246A1FA6}.Release|Any CPU.Build.0 = Release|Any CPU
42+
{715D2F11-3AAF-476E-9A6A-DCA6DEBD377E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
43+
{715D2F11-3AAF-476E-9A6A-DCA6DEBD377E}.Debug|Any CPU.Build.0 = Debug|Any CPU
44+
{715D2F11-3AAF-476E-9A6A-DCA6DEBD377E}.Release|Any CPU.ActiveCfg = Release|Any CPU
45+
{715D2F11-3AAF-476E-9A6A-DCA6DEBD377E}.Release|Any CPU.Build.0 = Release|Any CPU
4046
EndGlobalSection
4147
GlobalSection(SolutionProperties) = preSolution
4248
HideSolutionNode = FALSE
@@ -46,6 +52,7 @@ Global
4652
{EAE7B507-D908-4650-A301-C3341F005A51} = {DAB3DD1E-AD99-46C9-AC42-07E2F03D5A06}
4753
{8DBCF7DE-532D-45DF-A6B8-5D89415C5B77} = {DD273D5E-6D6C-41FA-A0C8-646CC53C4DC3}
4854
{2F99B66F-A347-4E8D-8ACA-5A34246A1FA6} = {DAB3DD1E-AD99-46C9-AC42-07E2F03D5A06}
55+
{715D2F11-3AAF-476E-9A6A-DCA6DEBD377E} = {DD273D5E-6D6C-41FA-A0C8-646CC53C4DC3}
4956
EndGlobalSection
5057
GlobalSection(ExtensibilityGlobals) = postSolution
5158
SolutionGuid = {96973E0C-81D1-42DE-9F78-7103241B4E07}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<Import Project="..\..\build\common.props" />
4+
5+
<PropertyGroup>
6+
<TargetFrameworks>net451;netstandard1.3</TargetFrameworks>
7+
<Description>A toolkit that provides a lightweight starter kit for using an in-memory Repository pattern (for testing purposes only).</Description>
8+
<AssemblyName>DotNetToolkit.Repository.InMemory</AssemblyName>
9+
<RootNamespace>DotNetToolkit.Repository.InMemory</RootNamespace>
10+
</PropertyGroup>
11+
12+
<ItemGroup>
13+
<ProjectReference Include="..\DotNetToolkit.Repository\DotNetToolkit.Repository.csproj" />
14+
</ItemGroup>
15+
16+
<ItemGroup>
17+
<Compile Update="Properties\Resources.Designer.cs">
18+
<DesignTime>True</DesignTime>
19+
<AutoGen>True</AutoGen>
20+
<DependentUpon>Resources.resx</DependentUpon>
21+
</Compile>
22+
</ItemGroup>
23+
24+
<ItemGroup>
25+
<EmbeddedResource Update="Properties\Resources.resx">
26+
<Generator>ResXFileCodeGenerator</Generator>
27+
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
28+
</EmbeddedResource>
29+
</ItemGroup>
30+
31+
</Project>
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
namespace DotNetToolkit.Repository.InMemory
2+
{
3+
4+
/// <summary>
5+
/// Represents a repository for in-memory operations (for testing purposes).
6+
/// </summary>
7+
public class InMemoryRepository<TEntity, TKey> : InMemoryRepositoryBase<TEntity, TKey> where TEntity : class
8+
{
9+
#region Constructors
10+
11+
/// <summary>
12+
/// Initializes a new instance of the <see cref="InMemoryRepository{TEntity,TKey}"/> class.
13+
/// </summary>
14+
/// <param name="databaseName">The name of the in-memory database. This allows the scope of the in-memory database to be controlled independently of the context.</param>
15+
public InMemoryRepository(string databaseName = null) : base(databaseName)
16+
{
17+
}
18+
19+
#endregion
20+
}
21+
22+
/// <summary>
23+
/// Represents a repository for in-memory operations with a default primary key value of type integer (for testing purposes).
24+
/// </summary>
25+
public class InMemoryRepository<TEntity> : InMemoryRepositoryBase<TEntity, int>, IRepository<TEntity> where TEntity : class
26+
{
27+
#region Constructors
28+
29+
/// <summary>
30+
/// Initializes a new instance of the <see cref="InMemoryRepository{TEntity}"/> class.
31+
/// </summary>
32+
/// <param name="databaseName">The name of the in-memory database. This allows the scope of the in-memory database to be controlled independently of the context.</param>
33+
public InMemoryRepository(string databaseName = null) : base(databaseName)
34+
{
35+
}
36+
37+
#endregion
38+
}
39+
}
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
namespace DotNetToolkit.Repository.InMemory
2+
{
3+
using FetchStrategies;
4+
using Internal;
5+
using System;
6+
using System.Linq;
7+
8+
/// <summary>
9+
/// Represents a repository for in-memory operations (for testing purposes).
10+
/// </summary>
11+
public abstract class InMemoryRepositoryBase<TEntity, TKey> : RepositoryBase<TEntity, TKey> where TEntity : class
12+
{
13+
#region Fields
14+
15+
private readonly InMemoryStore _store;
16+
private bool _disposed;
17+
18+
#endregion
19+
20+
#region Constructors
21+
22+
/// <summary>
23+
/// Initializes a new instance of the <see cref="InMemoryRepositoryBase{TEntity,TKey}"/> class.
24+
/// </summary>
25+
/// <param name="databaseName">The name of the in-memory database. This allows the scope of the in-memory database to be controlled independently of the context.</param>
26+
protected InMemoryRepositoryBase(string databaseName = null)
27+
{
28+
_store = new InMemoryStore(databaseName);
29+
}
30+
31+
#endregion
32+
33+
#region Protected Methods
34+
35+
/// <summary>
36+
/// Releases unmanaged and - optionally - managed resources.
37+
/// </summary>
38+
/// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
39+
protected virtual void Dispose(bool disposing)
40+
{
41+
if (_disposed) return;
42+
43+
if (disposing)
44+
{
45+
if (_store != null)
46+
{
47+
_store.Dispose();
48+
}
49+
}
50+
51+
_disposed = true;
52+
}
53+
54+
#endregion
55+
56+
#region Overrides of RepositoryBase<TEntity,TKey>
57+
58+
/// <summary>
59+
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
60+
/// </summary>
61+
public override void Dispose()
62+
{
63+
Dispose(true);
64+
GC.SuppressFinalize(this);
65+
}
66+
67+
/// <summary>
68+
/// A protected overridable method for adding the specified <paramref name="entity" /> into the repository.
69+
/// </summary>
70+
protected override void AddItem(TEntity entity)
71+
{
72+
if (entity == null)
73+
throw new ArgumentNullException(nameof(entity));
74+
75+
_store.Add(entity);
76+
}
77+
78+
/// <summary>
79+
/// A protected overridable method for deleting the specified <paramref name="entity" /> from the repository.
80+
/// </summary>
81+
protected override void DeleteItem(TEntity entity)
82+
{
83+
if (entity == null)
84+
throw new ArgumentNullException(nameof(entity));
85+
86+
_store.Remove(entity);
87+
}
88+
89+
/// <summary>
90+
/// A protected overridable method for updating the specified <paramref name="entity" /> in the repository.
91+
/// </summary>
92+
protected override void UpdateItem(TEntity entity)
93+
{
94+
if (entity == null)
95+
throw new ArgumentNullException(nameof(entity));
96+
97+
_store.Update(entity);
98+
}
99+
100+
/// <summary>
101+
/// A protected overridable method for saving changes made in the current unit of work in the repository.
102+
/// </summary>
103+
protected override void SaveChanges()
104+
{
105+
_store.SaveChanges();
106+
}
107+
108+
/// <summary>
109+
/// A protected overridable method for getting an entity query that supplies the specified fetching strategy from the repository.
110+
/// </summary>
111+
protected override IQueryable<TEntity> GetQuery(IFetchStrategy<TEntity> fetchStrategy = null)
112+
{
113+
return _store.Query<TEntity>();
114+
}
115+
116+
#endregion
117+
}
118+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
namespace DotNetToolkit.Repository.InMemory
2+
{
3+
/// <summary>
4+
/// An implementation of <see cref="IRepositoryFactory" />.
5+
/// </summary>
6+
public class InMemoryRepositoryFactory : IRepositoryFactory
7+
{
8+
#region Implementation of IRepositoryFactory
9+
10+
/// <summary>
11+
/// Creates a new repository for the specified entity type.
12+
/// </summary>
13+
/// <typeparam name="TEntity">The type of the entity.</typeparam>
14+
/// <param name="options">The options.</param>
15+
/// <returns>The new repository.</returns>
16+
public IRepository<TEntity> Create<TEntity>(IRepositoryOptions options) where TEntity : class
17+
{
18+
return new InMemoryRepository<TEntity>(options.ConnectionString);
19+
}
20+
21+
/// <summary>
22+
/// Creates a new repository for the specified entity and primary key type.
23+
/// </summary>
24+
/// <typeparam name="TEntity">The type of the entity.</typeparam>
25+
/// <typeparam name="TKey">The type of the key primary key value.</typeparam>
26+
/// <param name="options">The options.</param>
27+
/// <returns>The new repository.</returns>
28+
public IRepository<TEntity, TKey> Create<TEntity, TKey>(IRepositoryOptions options) where TEntity : class
29+
{
30+
return new InMemoryRepository<TEntity, TKey>(options.ConnectionString);
31+
}
32+
33+
#endregion
34+
}
35+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
namespace DotNetToolkit.Repository.InMemory.Internal
2+
{
3+
using System;
4+
5+
/// <summary>
6+
/// Represents an internal entity set in the in-memory store, which holds the entity and it's state representing the operation that was performed at the time.
7+
/// </summary>
8+
internal class EntitySet
9+
{
10+
#region Constructors
11+
12+
/// <summary>
13+
/// Initializes a new instance of the <see cref="EntitySet"/> class.
14+
/// </summary>
15+
/// <param name="entity">The entity.</param>
16+
/// <param name="state">The state.</param>
17+
public EntitySet(object entity, EntityState state)
18+
{
19+
Entity = entity;
20+
State = state;
21+
TimeStamp = TimeStamp = DateTime.Now.ToString("yyyyMMddHHmmssffff");
22+
}
23+
24+
#endregion
25+
26+
#region Properties
27+
28+
/// <summary>
29+
/// Gets the state.
30+
/// </summary>
31+
public EntityState State { get; }
32+
33+
/// <summary>
34+
/// Gets the entity.
35+
/// </summary>
36+
public object Entity { get; }
37+
38+
/// <summary>
39+
/// Gets the entity timestamp.
40+
/// </summary>
41+
public string TimeStamp { get; }
42+
43+
/// <summary>
44+
/// Gets the order.
45+
/// </summary>
46+
public int Order { get; set; }
47+
48+
#endregion
49+
}
50+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
namespace DotNetToolkit.Repository.InMemory.Internal
2+
{
3+
/// <summary>
4+
/// Represents an internal state for an entity in the in-memory store.
5+
/// </summary>
6+
internal enum EntityState
7+
{
8+
Added,
9+
Removed,
10+
Modified,
11+
Unchanged
12+
}
13+
}

0 commit comments

Comments
 (0)