Skip to content

Commit 89697c1

Browse files
authored
Added WPF example - non-working (#75)
1 parent 995b646 commit 89697c1

File tree

27 files changed

+744
-91
lines changed

27 files changed

+744
-91
lines changed

samples/datasync-server/Sample.Datasync.Server.sln

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample.Datasync.Server", "s
99
EndProject
1010
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "library", "library", "{95358590-6440-469A-8A6A-6ACC47F52966}"
1111
EndProject
12-
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CommunityToolkit.Datasync.Server", "..\..\..\..\CommunityToolkit\Datasync\src\CommunityToolkit.Datasync.Server\CommunityToolkit.Datasync.Server.csproj", "{D42DBA41-28AA-4B6D-83A4-A5B839EC8B25}"
12+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CommunityToolkit.Datasync.Server.Abstractions", "..\..\src\CommunityToolkit.Datasync.Server.Abstractions\CommunityToolkit.Datasync.Server.Abstractions.csproj", "{54E9A0B2-A0B0-4CB1-8FAD-11DB9E4535A6}"
1313
EndProject
14-
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CommunityToolkit.Datasync.Server.Abstractions", "..\..\..\..\CommunityToolkit\Datasync\src\CommunityToolkit.Datasync.Server.Abstractions\CommunityToolkit.Datasync.Server.Abstractions.csproj", "{CECB1B21-46C7-4197-B8D2-EC54D0AF8145}"
14+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CommunityToolkit.Datasync.Server", "..\..\src\CommunityToolkit.Datasync.Server\CommunityToolkit.Datasync.Server.csproj", "{DEC37ED1-B52A-4287-8F63-8210328AFF70}"
1515
EndProject
16-
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CommunityToolkit.Datasync.Server.EntityFrameworkCore", "..\..\..\..\CommunityToolkit\Datasync\src\CommunityToolkit.Datasync.Server.EntityFrameworkCore\CommunityToolkit.Datasync.Server.EntityFrameworkCore.csproj", "{8CDD3736-4B8D-43F5-8F9A-222210D73DAC}"
16+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CommunityToolkit.Datasync.Server.EntityFrameworkCore", "..\..\src\CommunityToolkit.Datasync.Server.EntityFrameworkCore\CommunityToolkit.Datasync.Server.EntityFrameworkCore.csproj", "{2086DD5C-C7C1-4957-B667-847C5FEE832C}"
1717
EndProject
1818
Global
1919
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -25,26 +25,26 @@ Global
2525
{67A76156-0033-4085-86BE-558DC28688A6}.Debug|Any CPU.Build.0 = Debug|Any CPU
2626
{67A76156-0033-4085-86BE-558DC28688A6}.Release|Any CPU.ActiveCfg = Release|Any CPU
2727
{67A76156-0033-4085-86BE-558DC28688A6}.Release|Any CPU.Build.0 = Release|Any CPU
28-
{D42DBA41-28AA-4B6D-83A4-A5B839EC8B25}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
29-
{D42DBA41-28AA-4B6D-83A4-A5B839EC8B25}.Debug|Any CPU.Build.0 = Debug|Any CPU
30-
{D42DBA41-28AA-4B6D-83A4-A5B839EC8B25}.Release|Any CPU.ActiveCfg = Release|Any CPU
31-
{D42DBA41-28AA-4B6D-83A4-A5B839EC8B25}.Release|Any CPU.Build.0 = Release|Any CPU
32-
{CECB1B21-46C7-4197-B8D2-EC54D0AF8145}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
33-
{CECB1B21-46C7-4197-B8D2-EC54D0AF8145}.Debug|Any CPU.Build.0 = Debug|Any CPU
34-
{CECB1B21-46C7-4197-B8D2-EC54D0AF8145}.Release|Any CPU.ActiveCfg = Release|Any CPU
35-
{CECB1B21-46C7-4197-B8D2-EC54D0AF8145}.Release|Any CPU.Build.0 = Release|Any CPU
36-
{8CDD3736-4B8D-43F5-8F9A-222210D73DAC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
37-
{8CDD3736-4B8D-43F5-8F9A-222210D73DAC}.Debug|Any CPU.Build.0 = Debug|Any CPU
38-
{8CDD3736-4B8D-43F5-8F9A-222210D73DAC}.Release|Any CPU.ActiveCfg = Release|Any CPU
39-
{8CDD3736-4B8D-43F5-8F9A-222210D73DAC}.Release|Any CPU.Build.0 = Release|Any CPU
28+
{54E9A0B2-A0B0-4CB1-8FAD-11DB9E4535A6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
29+
{54E9A0B2-A0B0-4CB1-8FAD-11DB9E4535A6}.Debug|Any CPU.Build.0 = Debug|Any CPU
30+
{54E9A0B2-A0B0-4CB1-8FAD-11DB9E4535A6}.Release|Any CPU.ActiveCfg = Release|Any CPU
31+
{54E9A0B2-A0B0-4CB1-8FAD-11DB9E4535A6}.Release|Any CPU.Build.0 = Release|Any CPU
32+
{DEC37ED1-B52A-4287-8F63-8210328AFF70}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
33+
{DEC37ED1-B52A-4287-8F63-8210328AFF70}.Debug|Any CPU.Build.0 = Debug|Any CPU
34+
{DEC37ED1-B52A-4287-8F63-8210328AFF70}.Release|Any CPU.ActiveCfg = Release|Any CPU
35+
{DEC37ED1-B52A-4287-8F63-8210328AFF70}.Release|Any CPU.Build.0 = Release|Any CPU
36+
{2086DD5C-C7C1-4957-B667-847C5FEE832C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
37+
{2086DD5C-C7C1-4957-B667-847C5FEE832C}.Debug|Any CPU.Build.0 = Debug|Any CPU
38+
{2086DD5C-C7C1-4957-B667-847C5FEE832C}.Release|Any CPU.ActiveCfg = Release|Any CPU
39+
{2086DD5C-C7C1-4957-B667-847C5FEE832C}.Release|Any CPU.Build.0 = Release|Any CPU
4040
EndGlobalSection
4141
GlobalSection(SolutionProperties) = preSolution
4242
HideSolutionNode = FALSE
4343
EndGlobalSection
4444
GlobalSection(NestedProjects) = preSolution
4545
{67A76156-0033-4085-86BE-558DC28688A6} = {4B8E4DD5-C2CA-4729-A10B-8A3C993018EC}
46-
{D42DBA41-28AA-4B6D-83A4-A5B839EC8B25} = {95358590-6440-469A-8A6A-6ACC47F52966}
47-
{CECB1B21-46C7-4197-B8D2-EC54D0AF8145} = {95358590-6440-469A-8A6A-6ACC47F52966}
48-
{8CDD3736-4B8D-43F5-8F9A-222210D73DAC} = {95358590-6440-469A-8A6A-6ACC47F52966}
46+
{54E9A0B2-A0B0-4CB1-8FAD-11DB9E4535A6} = {95358590-6440-469A-8A6A-6ACC47F52966}
47+
{DEC37ED1-B52A-4287-8F63-8210328AFF70} = {95358590-6440-469A-8A6A-6ACC47F52966}
48+
{2086DD5C-C7C1-4957-B667-847C5FEE832C} = {95358590-6440-469A-8A6A-6ACC47F52966}
4949
EndGlobalSection
5050
EndGlobal

samples/datasync-server/src/Sample.Datasync.Server/Db/TodoItem.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ namespace Sample.Datasync.Server.Db;
1010
public class TodoItem : EntityTableData
1111
{
1212
[Required, MinLength(1)]
13-
public string Text { get; set; } = string.Empty;
13+
public string Title { get; set; } = string.Empty;
1414

1515
public bool IsComplete { get; set; }
1616
}

samples/datasync-server/src/Sample.Datasync.Server/Sample.Datasync.Server.csproj

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@
2222
</ItemGroup>
2323

2424
<ItemGroup>
25-
<ProjectReference Include="..\..\..\..\..\..\CommunityToolkit\Datasync\src\CommunityToolkit.Datasync.Server.Abstractions\CommunityToolkit.Datasync.Server.Abstractions.csproj" />
26-
<ProjectReference Include="..\..\..\..\..\..\CommunityToolkit\Datasync\src\CommunityToolkit.Datasync.Server.EntityFrameworkCore\CommunityToolkit.Datasync.Server.EntityFrameworkCore.csproj" />
27-
<ProjectReference Include="..\..\..\..\..\..\CommunityToolkit\Datasync\src\CommunityToolkit.Datasync.Server\CommunityToolkit.Datasync.Server.csproj" />
25+
<ProjectReference Include="..\..\..\..\src\CommunityToolkit.Datasync.Server.Abstractions\CommunityToolkit.Datasync.Server.Abstractions.csproj" />
26+
<ProjectReference Include="..\..\..\..\src\CommunityToolkit.Datasync.Server.EntityFrameworkCore\CommunityToolkit.Datasync.Server.EntityFrameworkCore.csproj" />
27+
<ProjectReference Include="..\..\..\..\src\CommunityToolkit.Datasync.Server\CommunityToolkit.Datasync.Server.csproj" />
2828
</ItemGroup>
2929

3030
</Project>

samples/todoapp/Samples.TodoApp.sln

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TodoApp.WinUI3", "TodoApp.W
99
EndProject
1010
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CommunityToolkit.Datasync.Client", "..\..\src\CommunityToolkit.Datasync.Client\CommunityToolkit.Datasync.Client.csproj", "{2AC73FBE-9E76-4702-B551-B5884383CC68}"
1111
EndProject
12+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TodoApp.WPF", "TodoApp.WPF\TodoApp.WPF.csproj", "{410D4BBD-5ED7-4BC0-A2CF-547A4784732F}"
13+
EndProject
14+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample.Datasync.Server", "..\datasync-server\src\Sample.Datasync.Server\Sample.Datasync.Server.csproj", "{E67734DD-B397-4A65-AA50-D62F37EF05DD}"
15+
EndProject
1216
Global
1317
GlobalSection(SolutionConfigurationPlatforms) = preSolution
1418
Debug|Any CPU = Debug|Any CPU
@@ -61,6 +65,38 @@ Global
6165
{2AC73FBE-9E76-4702-B551-B5884383CC68}.Release|x64.Build.0 = Release|Any CPU
6266
{2AC73FBE-9E76-4702-B551-B5884383CC68}.Release|x86.ActiveCfg = Release|Any CPU
6367
{2AC73FBE-9E76-4702-B551-B5884383CC68}.Release|x86.Build.0 = Release|Any CPU
68+
{410D4BBD-5ED7-4BC0-A2CF-547A4784732F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
69+
{410D4BBD-5ED7-4BC0-A2CF-547A4784732F}.Debug|Any CPU.Build.0 = Debug|Any CPU
70+
{410D4BBD-5ED7-4BC0-A2CF-547A4784732F}.Debug|ARM64.ActiveCfg = Debug|Any CPU
71+
{410D4BBD-5ED7-4BC0-A2CF-547A4784732F}.Debug|ARM64.Build.0 = Debug|Any CPU
72+
{410D4BBD-5ED7-4BC0-A2CF-547A4784732F}.Debug|x64.ActiveCfg = Debug|Any CPU
73+
{410D4BBD-5ED7-4BC0-A2CF-547A4784732F}.Debug|x64.Build.0 = Debug|Any CPU
74+
{410D4BBD-5ED7-4BC0-A2CF-547A4784732F}.Debug|x86.ActiveCfg = Debug|Any CPU
75+
{410D4BBD-5ED7-4BC0-A2CF-547A4784732F}.Debug|x86.Build.0 = Debug|Any CPU
76+
{410D4BBD-5ED7-4BC0-A2CF-547A4784732F}.Release|Any CPU.ActiveCfg = Release|Any CPU
77+
{410D4BBD-5ED7-4BC0-A2CF-547A4784732F}.Release|Any CPU.Build.0 = Release|Any CPU
78+
{410D4BBD-5ED7-4BC0-A2CF-547A4784732F}.Release|ARM64.ActiveCfg = Release|Any CPU
79+
{410D4BBD-5ED7-4BC0-A2CF-547A4784732F}.Release|ARM64.Build.0 = Release|Any CPU
80+
{410D4BBD-5ED7-4BC0-A2CF-547A4784732F}.Release|x64.ActiveCfg = Release|Any CPU
81+
{410D4BBD-5ED7-4BC0-A2CF-547A4784732F}.Release|x64.Build.0 = Release|Any CPU
82+
{410D4BBD-5ED7-4BC0-A2CF-547A4784732F}.Release|x86.ActiveCfg = Release|Any CPU
83+
{410D4BBD-5ED7-4BC0-A2CF-547A4784732F}.Release|x86.Build.0 = Release|Any CPU
84+
{E67734DD-B397-4A65-AA50-D62F37EF05DD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
85+
{E67734DD-B397-4A65-AA50-D62F37EF05DD}.Debug|Any CPU.Build.0 = Debug|Any CPU
86+
{E67734DD-B397-4A65-AA50-D62F37EF05DD}.Debug|ARM64.ActiveCfg = Debug|Any CPU
87+
{E67734DD-B397-4A65-AA50-D62F37EF05DD}.Debug|ARM64.Build.0 = Debug|Any CPU
88+
{E67734DD-B397-4A65-AA50-D62F37EF05DD}.Debug|x64.ActiveCfg = Debug|Any CPU
89+
{E67734DD-B397-4A65-AA50-D62F37EF05DD}.Debug|x64.Build.0 = Debug|Any CPU
90+
{E67734DD-B397-4A65-AA50-D62F37EF05DD}.Debug|x86.ActiveCfg = Debug|Any CPU
91+
{E67734DD-B397-4A65-AA50-D62F37EF05DD}.Debug|x86.Build.0 = Debug|Any CPU
92+
{E67734DD-B397-4A65-AA50-D62F37EF05DD}.Release|Any CPU.ActiveCfg = Release|Any CPU
93+
{E67734DD-B397-4A65-AA50-D62F37EF05DD}.Release|Any CPU.Build.0 = Release|Any CPU
94+
{E67734DD-B397-4A65-AA50-D62F37EF05DD}.Release|ARM64.ActiveCfg = Release|Any CPU
95+
{E67734DD-B397-4A65-AA50-D62F37EF05DD}.Release|ARM64.Build.0 = Release|Any CPU
96+
{E67734DD-B397-4A65-AA50-D62F37EF05DD}.Release|x64.ActiveCfg = Release|Any CPU
97+
{E67734DD-B397-4A65-AA50-D62F37EF05DD}.Release|x64.Build.0 = Release|Any CPU
98+
{E67734DD-B397-4A65-AA50-D62F37EF05DD}.Release|x86.ActiveCfg = Release|Any CPU
99+
{E67734DD-B397-4A65-AA50-D62F37EF05DD}.Release|x86.Build.0 = Release|Any CPU
64100
EndGlobalSection
65101
GlobalSection(SolutionProperties) = preSolution
66102
HideSolutionNode = FALSE

samples/todoapp/TodoApp.WPF/App.xaml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<Application x:Class="TodoApp.WPF.App"
2+
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3+
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4+
xmlns:local="clr-namespace:TodoApp.WPF"
5+
StartupUri="MainWindow.xaml">
6+
<Application.Resources>
7+
8+
</Application.Resources>
9+
</Application>
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
using Microsoft.Data.Sqlite;
6+
using Microsoft.EntityFrameworkCore;
7+
using Microsoft.Extensions.DependencyInjection;
8+
using System.Windows;
9+
using TodoApp.WPF.Database;
10+
using TodoApp.WPF.ViewModels;
11+
12+
namespace TodoApp.WPF;
13+
14+
/// <summary>
15+
/// Interaction logic for App.xaml
16+
/// </summary>
17+
public partial class App : Application, IDisposable
18+
{
19+
private readonly SqliteConnection dbConnection;
20+
21+
/// <summary>
22+
/// The IoC service provider
23+
/// </summary>
24+
public IServiceProvider Services { get; }
25+
26+
public App()
27+
{
28+
// Create the connection to the SQLite database
29+
this.dbConnection = new SqliteConnection("Data Source=:memory:");
30+
this.dbConnection.Open();
31+
32+
// Create the IoC Services provider.
33+
Services = new ServiceCollection()
34+
.AddTransient<TodoListViewModel>()
35+
.AddScoped<IDbInitializer, DbContextInitializer>()
36+
.AddDbContext<AppDbContext>(options => options.UseSqlite(this.dbConnection))
37+
.BuildServiceProvider();
38+
39+
// Initialize the database
40+
InitializeDatabase();
41+
}
42+
43+
private void InitializeDatabase()
44+
{
45+
// using IServiceScope scope = Ioc.Default.CreateScope();
46+
using IServiceScope scope = Services.CreateScope();
47+
IDbInitializer initializer = scope.ServiceProvider.GetRequiredService<IDbInitializer>();
48+
initializer.Initialize();
49+
}
50+
51+
/// <summary>
52+
/// A helper method for getting a service from the services collection.
53+
/// </summary>
54+
/// <remarks>
55+
/// You can see this in action in the <see cref="TodoListPage"/> class.
56+
/// </remarks>
57+
/// <typeparam name="TService">The type of the service.</typeparam>
58+
/// <returns>An instance of the service</returns>
59+
public static TService GetRequiredService<TService>() where TService : notnull
60+
=> ((App)App.Current).Services.GetRequiredService<TService>();
61+
62+
#region IDisposable
63+
private bool hasDisposed;
64+
65+
protected virtual void Dispose(bool disposing)
66+
{
67+
if (!this.hasDisposed)
68+
{
69+
if (disposing)
70+
{
71+
this.dbConnection.Close();
72+
}
73+
74+
this.hasDisposed = true;
75+
}
76+
}
77+
78+
public void Dispose()
79+
{
80+
Dispose(disposing: true);
81+
GC.SuppressFinalize(this);
82+
}
83+
#endregion
84+
}
85+
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
using System.Windows;
6+
7+
[assembly: ThemeInfo(
8+
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
9+
//(used if a resource is not found in the page,
10+
// or application resource dictionaries)
11+
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
12+
//(used if a resource is not found in the page,
13+
// app, or any theme specific resource dictionaries)
14+
)]
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
using CommunityToolkit.Datasync.Client.Http;
6+
using CommunityToolkit.Datasync.Client.Offline;
7+
using Microsoft.EntityFrameworkCore;
8+
using TodoApp.WPF.Services;
9+
10+
namespace TodoApp.WPF.Database;
11+
12+
public class AppDbContext(DbContextOptions<AppDbContext> options) : DbContext(options)
13+
{
14+
public DbSet<TodoItem> TodoItems => Set<TodoItem>();
15+
16+
// protected override void OnDatasyncInitialization(DatasyncOfflineOptionsBuilder optionsBuilder)
17+
// {
18+
// HttpClientOptions clientOptions = new()
19+
// {
20+
// Endpoint = new Uri("https://Y.azurewebsites.net/"),
21+
// HttpPipeline = [new LoggingHandler()]
22+
// };
23+
// _ = optionsBuilder.UseHttpClientOptions(clientOptions);
24+
// }
25+
26+
public async Task SynchronizeAsync(CancellationToken cancellationToken = default)
27+
{
28+
// PushResult pushResult = await this.PushAsync(cancellationToken);
29+
// if (!pushResult.IsSuccessful)
30+
// {
31+
// throw new ApplicationException($"Push failed: {pushResult.FailedRequests.FirstOrDefault().Value.ReasonPhrase}");
32+
// }
33+
34+
// PullResult pullResult = await this.PullAsync(cancellationToken);
35+
// if (!pullResult.IsSuccessful)
36+
// {
37+
// throw new ApplicationException($"Pull failed: {pullResult.FailedRequests.FirstOrDefault().Value.ReasonPhrase}");
38+
// }
39+
}
40+
}
41+
42+
/// <summary>
43+
/// Use this class to initialize the database. In this sample, we just create
44+
/// the database using <see cref="DatabaseFacade.EnsureCreated"/>. However, you
45+
/// may want to use migrations.
46+
/// </summary>
47+
/// <param name="context">The context for the database.</param>
48+
public class DbContextInitializer(AppDbContext context) : IDbInitializer
49+
{
50+
/// <inheritdoc />
51+
public void Initialize()
52+
=> context.Database.EnsureCreated();
53+
54+
/// <inheritdoc />
55+
public Task InitializeAsync(CancellationToken cancellationToken = default)
56+
=> context.Database.EnsureCreatedAsync(cancellationToken);
57+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
namespace TodoApp.WPF.Database;
6+
7+
/// <summary>
8+
/// An interface to initialize a database.
9+
/// </summary>
10+
public interface IDbInitializer
11+
{
12+
/// <summary>
13+
/// Synchronously initialize the database.
14+
/// </summary>
15+
void Initialize();
16+
17+
/// <summary>
18+
/// Asynchronously initialize the database.
19+
/// </summary>
20+
/// <param name="cancellationToken">A <see cref="CancellationToken"/> to observe.</param>
21+
/// <returns>A task that resolves when complete.</returns>
22+
Task InitializeAsync(CancellationToken cancellationToken = default);
23+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
using System.ComponentModel.DataAnnotations;
6+
7+
namespace TodoApp.WPF.Database;
8+
9+
/// <summary>
10+
/// An abstract class for working with offline entities.
11+
/// </summary>
12+
public abstract class OfflineClientEntity
13+
{
14+
[Key]
15+
public string Id { get; set; } = Guid.NewGuid().ToString("N");
16+
public DateTimeOffset? UpdatedAt { get; set; }
17+
public string? Version { get; set; }
18+
public bool Deleted { get; set; }
19+
}

0 commit comments

Comments
 (0)