Skip to content
This repository was archived by the owner on May 10, 2020. It is now read-only.

Commit 1e563e8

Browse files
committed
V0.7.0
1 parent 303093a commit 1e563e8

31 files changed

+318
-232
lines changed

BlazorDB.sln

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BlazorDB", "src\BlazorDB\Bl
77
EndProject
88
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample", "src\Sample\Sample.csproj", "{DAABB1BD-F735-4AB8-8ECF-70E00048175B}"
99
EndProject
10-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FluxorIntegration", "src\FluxorIntegration\FluxorIntegration.csproj", "{9C42034D-6331-4623-B178-7417F9AB1345}"
11-
EndProject
1210
Global
1311
GlobalSection(SolutionConfigurationPlatforms) = preSolution
1412
Debug|Any CPU = Debug|Any CPU
@@ -23,10 +21,6 @@ Global
2321
{DAABB1BD-F735-4AB8-8ECF-70E00048175B}.Debug|Any CPU.Build.0 = Debug|Any CPU
2422
{DAABB1BD-F735-4AB8-8ECF-70E00048175B}.Release|Any CPU.ActiveCfg = Release|Any CPU
2523
{DAABB1BD-F735-4AB8-8ECF-70E00048175B}.Release|Any CPU.Build.0 = Release|Any CPU
26-
{9C42034D-6331-4623-B178-7417F9AB1345}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
27-
{9C42034D-6331-4623-B178-7417F9AB1345}.Debug|Any CPU.Build.0 = Debug|Any CPU
28-
{9C42034D-6331-4623-B178-7417F9AB1345}.Release|Any CPU.ActiveCfg = Release|Any CPU
29-
{9C42034D-6331-4623-B178-7417F9AB1345}.Release|Any CPU.Build.0 = Release|Any CPU
3024
EndGlobalSection
3125
GlobalSection(SolutionProperties) = preSolution
3226
HideSolutionNode = FALSE

README.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,22 @@ In memory, persisted to localstorage, database for .net Blazor browser framework
44
## Warning
55
This library like Blazor itself is experimental and API is likely to change.
66

7+
## Breaking change as of V0.7.0
8+
9+
At this time, you will need to initialize the `Context` prior to using it. I hope that I cna get this done automatically again in a future version:
10+
11+
```
12+
protected async override Task OnInitAsync()
13+
{
14+
await Context.Initialize();
15+
}
16+
```
17+
18+
## Note about the sample project
19+
20+
The Todo page does not work fully. The TodoForm that allows you to edit an item or add a new item is not working correctly. The OnInitAsync in the
21+
child component is not firing. However, since BlazorDB itself it working, I decided to publish the version and figure out the Sample app afterwards.
22+
723
## Docs
824

925
### Install
@@ -67,6 +83,15 @@ Inject your context into your component:
6783
@inject Context Context
6884
```
6985

86+
Currently, as of v0.7.0, before using the `Context` object you must initialize it. Hopefully, this requirement will go away in a future version:
87+
88+
```
89+
protected async override Task OnInitAsync()
90+
{
91+
await Context.Initialize();
92+
}
93+
```
94+
7095
Create a model and add it to your Context:
7196

7297
```

src/BlazorDB/BlazorDB.csproj

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
<BlazorLinkOnBuild>false</BlazorLinkOnBuild>
88
<LangVersion>7.3</LangVersion>
99
<PackageId>BlazorDB</PackageId>
10-
<Version>0.2.0</Version>
10+
<Version>0.7.0</Version>
1111
<Authors>Chanan Braunstein</Authors>
1212
<Title>Blazor localStorage Database</Title>
1313
<Description>In memory, persisted to localstorage, database for .net Blazor browser framework</Description>
@@ -23,9 +23,9 @@
2323
</ItemGroup>
2424

2525
<ItemGroup>
26-
<PackageReference Include="BlazorLogger" Version="0.2.0" />
27-
<PackageReference Include="Microsoft.AspNetCore.Blazor.Browser" Version="0.4.0" />
28-
<PackageReference Include="Microsoft.AspNetCore.Blazor.Build" Version="0.4.0" />
26+
<PackageReference Include="BlazorLogger" Version="0.7.0" />
27+
<PackageReference Include="Microsoft.AspNetCore.Blazor.Browser" Version="0.7.0" />
28+
<PackageReference Include="Microsoft.AspNetCore.Blazor.Build" Version="0.7.0" />
2929
</ItemGroup>
3030

3131
</Project>

src/BlazorDB/IStorageContext.cs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1-
namespace BlazorDB
1+
using System.Threading.Tasks;
2+
3+
namespace BlazorDB
24
{
35
public interface IStorageContext
46
{
5-
int SaveChanges();
6-
void LogToConsole();
7+
Task<int> SaveChanges();
8+
Task LogToConsole();
79
}
810
}

src/BlazorDB/ServiceCollectionExtensions.cs

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
using System.Collections.Generic;
55
using System.Linq;
66
using System.Reflection;
7+
using System.Threading.Tasks;
8+
using Microsoft.JSInterop;
79

810
namespace BlazorDB
911
{
@@ -26,14 +28,19 @@ public static IServiceCollection AddBlazorDB(this IServiceCollection serviceColl
2628
private static void Scan(IServiceCollection serviceCollection, Assembly assembly)
2729
{
2830
var types = ScanForContexts(serviceCollection, assembly);
29-
RegisterBlazorDb(serviceCollection, types);
30-
}
31-
32-
private static void RegisterBlazorDb(IServiceCollection serviceCollection, IEnumerable<Type> types)
33-
{
3431
serviceCollection.AddSingleton(StorageManager);
35-
foreach (var contextType in types)
36-
StorageManager.LoadContextFromStorageOrCreateNew(serviceCollection, contextType);
32+
33+
foreach (var type in types)
34+
{
35+
serviceCollection.AddSingleton(type, s =>
36+
{
37+
var jsRuntime = s.GetRequiredService<IJSRuntime>();
38+
var instance = Activator.CreateInstance(type);
39+
var smProp = type.GetProperty("StorageManager", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
40+
smProp.SetValue(instance, StorageManager);
41+
return instance;
42+
});
43+
}
3744
}
3845

3946
private static IEnumerable<Type> ScanForContexts(IServiceCollection serviceCollection, Assembly assembly)
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
using Microsoft.Extensions.DependencyInjection;
2-
using System;
1+
using System;
2+
using System.Threading.Tasks;
33

44
namespace BlazorDB.Storage
55
{
66
public interface IStorageManager
77
{
8-
int SaveContextToLocalStorage(StorageContext context);
9-
void LoadContextFromStorageOrCreateNew(IServiceCollection serviceCollection, Type contextType);
8+
Task<int> SaveContextToLocalStorage(StorageContext context);
9+
Task LoadContextFromLocalStorage(StorageContext context);
1010
}
1111
}

src/BlazorDB/Storage/Logger.cs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Threading.Tasks;
23

34
namespace BlazorDB.Storage
45
{
@@ -10,23 +11,23 @@ internal static class Logger
1011
private const string Normal = "color: black; font-style: normal;";
1112
internal static bool LogDebug { get; set; } = true;
1213

13-
internal static void LogStorageSetToConsole(Type type, object list)
14+
internal async static Task LogStorageSetToConsole(Type type, object list)
1415
{
1516
if (!LogDebug) return;
16-
BlazorLogger.Logger.Log($"StorageSet<{type.GetGenericArguments()[0].Name}>: %o", list);
17+
await BlazorLogger.Logger.Log($"StorageSet<{type.GetGenericArguments()[0].Name}>: %o", list);
1718
}
1819

19-
internal static void StartContextType(Type contextType, bool loading = true)
20+
internal async static Task StartContextType(Type contextType, bool loading = true)
2021
{
2122
if (!LogDebug) return;
22-
var message = loading ? " loading" : " log";
23-
BlazorLogger.Logger.GroupCollapsed($"Context{message}: %c{contextType.Namespace}.{contextType.Name}", Blue);
23+
var message = loading ? "loading" : "log";
24+
await BlazorLogger.Logger.GroupCollapsed($"Context {message}: %c{contextType.Namespace}.{contextType.Name}", Blue);
2425
}
2526

26-
internal static void ContextSaved(Type contextType)
27+
internal async static Task ContextSaved(Type contextType)
2728
{
2829
if (!LogDebug) return;
29-
BlazorLogger.Logger.GroupCollapsed($"Context %csaved: %c{contextType.Namespace}.{contextType.Name}", Green,
30+
await BlazorLogger.Logger.GroupCollapsed($"Context %csaved: %c{contextType.Namespace}.{contextType.Name}", Green,
3031
Blue);
3132
}
3233

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
using System;
2-
using Microsoft.Extensions.DependencyInjection;
2+
using System.Threading.Tasks;
33

44
namespace BlazorDB.Storage
55
{
@@ -8,14 +8,14 @@ internal class StorageManager : IStorageManager
88
private readonly StorageManagerLoad _storageManagerLoad = new StorageManagerLoad();
99
private readonly StorageManagerSave _storageManagerSave = new StorageManagerSave();
1010

11-
public int SaveContextToLocalStorage(StorageContext context)
11+
public Task<int> SaveContextToLocalStorage(StorageContext context)
1212
{
1313
return _storageManagerSave.SaveContextToLocalStorage(context);
1414
}
1515

16-
public void LoadContextFromStorageOrCreateNew(IServiceCollection serviceCollection, Type contextType)
16+
public Task LoadContextFromLocalStorage(StorageContext context)
1717
{
18-
_storageManagerLoad.LoadContextFromStorageOrCreateNew(serviceCollection, contextType);
18+
return _storageManagerLoad.LoadContextFromLocalStorage(context);
1919
}
2020
}
2121
}

src/BlazorDB/Storage/StorageManagerLoad.cs

Lines changed: 20 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -3,40 +3,39 @@
33
using System.Linq;
44
using System.Reflection;
55
using System.Text;
6-
using Microsoft.AspNetCore.Blazor;
7-
using Microsoft.Extensions.DependencyInjection;
6+
using System.Threading.Tasks;
7+
using Microsoft.JSInterop;
88

99
namespace BlazorDB.Storage
1010
{
1111
internal class StorageManagerLoad
1212
{
13-
public void LoadContextFromStorageOrCreateNew(IServiceCollection serviceCollection, Type contextType)
13+
public async Task LoadContextFromLocalStorage(StorageContext context)
1414
{
15-
Logger.StartContextType(contextType);
15+
var contextType = context.GetType();
16+
await Logger.StartContextType(contextType);
1617
var storageSets = StorageManagerUtil.GetStorageSets(contextType);
17-
var stringModels = LoadStringModels(contextType, storageSets);
18+
var stringModels = await LoadStringModels(contextType, storageSets);
1819
//PrintStringModels(stringModels);
1920
stringModels = ScanNonAssociationModels(storageSets, stringModels);
2021
stringModels = ScanAssociationModels(storageSets, stringModels);
2122
stringModels = DeserializeModels(stringModels, storageSets);
2223
//PrintStringModels(stringModels);
23-
var context = CreateContext(contextType, stringModels);
24-
RegisterContext(serviceCollection, contextType, context);
24+
await EnrichContext(context, contextType, stringModels);
2525
Logger.EndGroup();
2626
}
2727

28-
private static object CreateContext(Type contextType,
28+
private static async Task EnrichContext(StorageContext context, Type contextType,
2929
IReadOnlyDictionary<Type, Dictionary<int, SerializedModel>> stringModels)
3030
{
31-
var context = Activator.CreateInstance(contextType);
3231
foreach (var prop in contextType.GetProperties())
3332
if (prop.PropertyType.IsGenericType &&
3433
prop.PropertyType.GetGenericTypeDefinition() == typeof(StorageSet<>))
3534
{
3635
var modelType = prop.PropertyType.GetGenericArguments()[0];
3736
var storageSetType = StorageManagerUtil.GenericStorageSetType.MakeGenericType(modelType);
3837
var storageTableName = Util.GetStorageTableName(contextType, modelType);
39-
var metadata = StorageManagerUtil.LoadMetadata(storageTableName);
38+
var metadata = await StorageManagerUtil.LoadMetadata(storageTableName);
4039
if (stringModels.ContainsKey(modelType))
4140
{
4241
var map = stringModels[modelType];
@@ -46,14 +45,11 @@ private static object CreateContext(Type contextType,
4645
{
4746
Logger.LoadModelInContext(modelType, 0);
4847
}
49-
5048
var storageSet = metadata != null
5149
? LoadStorageSet(storageSetType, contextType, modelType, stringModels[modelType])
5250
: CreateNewStorageSet(storageSetType, contextType);
5351
prop.SetValue(context, storageSet);
5452
}
55-
56-
return context;
5753
}
5854

5955
private static Dictionary<Type, Dictionary<int, SerializedModel>> DeserializeModels(
@@ -251,7 +247,7 @@ private static string FixAssociationsInStringModels(SerializedModel stringModel,
251247

252248
private static string ReplaceListWithAssociationList(string serializedModel, string propName, string strList)
253249
{
254-
var propStart = serializedModel.IndexOf($"\"{propName}\":[", StringComparison.Ordinal);
250+
var propStart = serializedModel.IndexOf($"\"{propName.ToCamelCase()}\":[", StringComparison.Ordinal);
255251
var start = serializedModel.IndexOf('[', propStart) + 1;
256252
var end = serializedModel.IndexOf(']', start);
257253
var result = StorageManagerUtil.ReplaceString(serializedModel, start, end, strList);
@@ -262,13 +258,13 @@ private static bool TryGetIdListFromSerializedModel(string serializedModel, stri
262258
out List<int> idList)
263259
{
264260
var list = new List<int>();
265-
if (serializedModel.IndexOf($"\"{propName}\":null", StringComparison.Ordinal) != -1)
261+
if (serializedModel.IndexOf($"\"{propName.ToCamelCase()}\":null", StringComparison.Ordinal) != -1)
266262
{
267263
idList = list;
268264
return false;
269265
}
270266

271-
var propStart = serializedModel.IndexOf($"\"{propName}\":[", StringComparison.Ordinal);
267+
var propStart = serializedModel.IndexOf($"\"{propName.ToCamelCase()}\":[", StringComparison.Ordinal);
272268
var start = serializedModel.IndexOf('[', propStart) + 1;
273269
var end = serializedModel.IndexOf(']', start);
274270
var stringlist = serializedModel.Substring(start, end - start);
@@ -297,7 +293,7 @@ private static bool IsScanDone(Dictionary<Type, Dictionary<int, SerializedModel>
297293
return done;
298294
}
299295

300-
private static Dictionary<Type, Dictionary<int, SerializedModel>> LoadStringModels(Type contextType,
296+
private static async Task<Dictionary<Type, Dictionary<int, SerializedModel>>> LoadStringModels(Type contextType,
301297
IEnumerable<PropertyInfo> storageSets)
302298
{
303299
var stringModels = new Dictionary<Type, Dictionary<int, SerializedModel>>();
@@ -306,12 +302,12 @@ private static Dictionary<Type, Dictionary<int, SerializedModel>> LoadStringMode
306302
var modelType = prop.PropertyType.GetGenericArguments()[0];
307303
var map = new Dictionary<int, SerializedModel>();
308304
var storageTableName = Util.GetStorageTableName(contextType, modelType);
309-
var metadata = StorageManagerUtil.LoadMetadata(storageTableName);
305+
var metadata = await StorageManagerUtil.LoadMetadata(storageTableName);
310306
if (metadata == null) continue;
311307
foreach (var guid in metadata.Guids)
312308
{
313309
var name = $"{storageTableName}-{guid}";
314-
var serializedModel = BlazorDBInterop.GetItem(name, false);
310+
var serializedModel = await BlazorDBInterop.GetItem(name, false);
315311
var id = FindIdInSerializedModel(serializedModel);
316312
map.Add(id, new SerializedModel {StringModel = serializedModel});
317313
}
@@ -325,13 +321,13 @@ private static Dictionary<Type, Dictionary<int, SerializedModel>> LoadStringMode
325321
//TODO: Verify that the found id is at the top level in case of nested objects
326322
private static bool TryGetIdFromSerializedModel(string serializedModel, string propName, out int id)
327323
{
328-
if (serializedModel.IndexOf($"\"{propName}\":null", StringComparison.Ordinal) != -1)
324+
if (serializedModel.IndexOf($"\"{propName.ToCamelCase()}\":null", StringComparison.Ordinal) != -1)
329325
{
330326
id = -1;
331327
return false;
332328
}
333329

334-
var propStart = serializedModel.IndexOf($"\"{propName}\":", StringComparison.Ordinal);
330+
var propStart = serializedModel.IndexOf($"\"{propName.ToCamelCase()}\":", StringComparison.Ordinal);
335331
var start = serializedModel.IndexOf(':', propStart);
336332
id = GetIdFromString(serializedModel, start);
337333
return true;
@@ -340,7 +336,7 @@ private static bool TryGetIdFromSerializedModel(string serializedModel, string p
340336
//TODO: Verify that the found id is at the top level in case of nested objects
341337
private static int FindIdInSerializedModel(string serializedModel)
342338
{
343-
var start = serializedModel.IndexOf($"\"{StorageManagerUtil.Id}\":", StringComparison.Ordinal);
339+
var start = serializedModel.IndexOf($"\"{StorageManagerUtil.Id.ToCamelCase()}\":", StringComparison.Ordinal);
344340
return GetIdFromString(serializedModel, start);
345341
}
346342

@@ -368,7 +364,7 @@ private static int GetIdFromString(string stringToSearch, int startFrom = 0)
368364

369365
private static string ReplaceIdWithAssociation(string result, string name, int id, string stringModel)
370366
{
371-
var stringToFind = $"\"{name}\":{id}";
367+
var stringToFind = $"\"{name.ToCamelCase()}\":{id}";
372368
var nameIndex = result.IndexOf(stringToFind, StringComparison.Ordinal);
373369
var index = result.IndexOf(id.ToString(), nameIndex, StringComparison.Ordinal);
374370
result = StorageManagerUtil.ReplaceString(result, index, index + id.ToString().Length, stringModel);
@@ -398,20 +394,13 @@ private static object DeserializeModel(Type modelType, string value)
398394
var model = genericMethod.Invoke(new JsonWrapper(), new object[] {value});
399395
return model;
400396
}
401-
402-
private static void RegisterContext(IServiceCollection serviceCollection, Type type, object context)
403-
{
404-
serviceCollection.AddSingleton(
405-
type,
406-
context);
407-
}
408397
}
409398

410399
internal class JsonWrapper
411400
{
412401
public T Deserialize<T>(string value)
413402
{
414-
return JsonUtil.Deserialize<T>(value);
403+
return Json.Deserialize<T>(value);
415404
}
416405
}
417406
}

0 commit comments

Comments
 (0)