diff --git a/.idea/.idea.HopFrame/.idea/projectSettingsUpdater.xml b/.idea/.idea.HopFrame/.idea/projectSettingsUpdater.xml
index 64af657..ef20cb0 100644
--- a/.idea/.idea.HopFrame/.idea/projectSettingsUpdater.xml
+++ b/.idea/.idea.HopFrame/.idea/projectSettingsUpdater.xml
@@ -2,6 +2,7 @@
+
\ No newline at end of file
diff --git a/.idea/.idea.HopFrame/.idea/workspace.xml b/.idea/.idea.HopFrame/.idea/workspace.xml
index 51a4601..7332fc3 100644
--- a/.idea/.idea.HopFrame/.idea/workspace.xml
+++ b/.idea/.idea.HopFrame/.idea/workspace.xml
@@ -12,13 +12,19 @@
-
-
+
+
+
+
+
+
+
-
-
-
+
+
+
+
@@ -117,7 +123,7 @@
"associatedIndex": 3
}
-
+
@@ -125,28 +131,28 @@
- {
- "keyToString": {
- ".NET Launch Settings Profile.HopFrame.Testing.Api: https.executor": "Run",
- ".NET Launch Settings Profile.HopFrame.Testing.executor": "Run",
- ".NET Launch Settings Profile.HopFrame.Testing: https.executor": "Run",
- ".NET Project.HopFrame.Testing.executor": "Run",
- "72b118b0-a6fc-4561-acdf-74f0b454dbb8.executor": "Debug",
- "RunOnceActivity.ShowReadmeOnStart": "true",
- "RunOnceActivity.git.unshallow": "true",
- "b5f11219-dfc4-47a1-b02c-90ab603034fb.executor": "Debug",
- "dcdf1689-dc07-47e4-8824-2e60a4fbf301.executor": "Debug",
- "git-widget-placeholder": "!35 on feature/advanced-search",
- "list.type.of.created.stylesheet": "CSS",
- "node.js.detected.package.eslint": "true",
- "node.js.detected.package.tslint": "true",
- "node.js.selected.package.eslint": "(autodetect)",
- "node.js.selected.package.tslint": "(autodetect)",
- "nodejs_package_manager_path": "npm",
- "settings.editor.selected.configurable": "preferences.pluginManager",
- "vue.rearranger.settings.migration": "true"
+
+}]]>
@@ -272,15 +278,8 @@
-
-
-
-
- 1736885531216
-
-
-
- 1736885531216
+
+
@@ -666,7 +665,15 @@
1742063374318
-
+
+
+ 1744971440348
+
+
+
+ 1744971440348
+
+
@@ -696,7 +703,6 @@
-
@@ -721,6 +727,38 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ file://$PROJECT_DIR$/src/HopFrame.Core/Services/Implementations/SearchExpressionBuilder.cs
+ 102
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/HopFrame.Core/ServiceCollectionExtensions.cs b/src/HopFrame.Core/ServiceCollectionExtensions.cs
index daf73dd..0d9ead1 100644
--- a/src/HopFrame.Core/ServiceCollectionExtensions.cs
+++ b/src/HopFrame.Core/ServiceCollectionExtensions.cs
@@ -17,6 +17,7 @@ public static class ServiceCollectionExtensions {
services.AddScoped();
services.TryAddScoped();
services.TryAddScoped();
+ services.AddScoped();
return services;
}
diff --git a/src/HopFrame.Core/Services/ISearchExpressionBuilder.cs b/src/HopFrame.Core/Services/ISearchExpressionBuilder.cs
new file mode 100644
index 0000000..5765e4c
--- /dev/null
+++ b/src/HopFrame.Core/Services/ISearchExpressionBuilder.cs
@@ -0,0 +1,9 @@
+using System.Linq.Expressions;
+using System.Reflection;
+using HopFrame.Core.Config;
+
+namespace HopFrame.Core.Services;
+
+public interface ISearchExpressionBuilder {
+ Expression? BuildSearchExpression(TableConfig table, string searchTerm, ParameterExpression parameter);
+}
\ No newline at end of file
diff --git a/src/HopFrame.Core/Services/Implementations/ContextExplorer.cs b/src/HopFrame.Core/Services/Implementations/ContextExplorer.cs
index e9b8dfe..b839bf3 100644
--- a/src/HopFrame.Core/Services/Implementations/ContextExplorer.cs
+++ b/src/HopFrame.Core/Services/Implementations/ContextExplorer.cs
@@ -50,12 +50,12 @@ internal sealed class ContextExplorer(HopFrameConfig config, IServiceProvider pr
if (context is DbContextConfig) {
var type = typeof(TableManager<>).MakeGenericType(table.TableType);
- return Activator.CreateInstance(type, (DbContext)repo, table, this, provider) as ITableManager;
+ return Activator.CreateInstance(type, (DbContext)repo, table, this, provider, provider.GetRequiredService()) as ITableManager;
}
if (context is RepositoryGroupConfig repoConfig) {
var type = typeof(RepositoryTableManager<,>).MakeGenericType(table.TableType, repoConfig.KeyProperty.PropertyType);
- return Activator.CreateInstance(type, repo, this, provider) as ITableManager;
+ return Activator.CreateInstance(type, repo, this, provider, provider.GetRequiredService()) as ITableManager;
}
}
@@ -72,12 +72,12 @@ internal sealed class ContextExplorer(HopFrameConfig config, IServiceProvider pr
if (context is DbContextConfig) {
var type = typeof(TableManager<>).MakeGenericType(table.TableType);
- return Activator.CreateInstance(type, (DbContext)repo, table, this, provider) as ITableManager;
+ return Activator.CreateInstance(type, (DbContext)repo, table, this, provider, provider.GetRequiredService()) as ITableManager;
}
if (context is RepositoryGroupConfig repoConfig) {
var type = typeof(RepositoryTableManager<,>).MakeGenericType(table.TableType, repoConfig.KeyProperty.PropertyType);
- return Activator.CreateInstance(type, repo, this, provider) as ITableManager;
+ return Activator.CreateInstance(type, repo, this, provider, provider.GetRequiredService()) as ITableManager;
}
}
diff --git a/src/HopFrame.Core/Services/Implementations/RepositoryTableManager.cs b/src/HopFrame.Core/Services/Implementations/RepositoryTableManager.cs
index f86ab10..541c203 100644
--- a/src/HopFrame.Core/Services/Implementations/RepositoryTableManager.cs
+++ b/src/HopFrame.Core/Services/Implementations/RepositoryTableManager.cs
@@ -3,7 +3,7 @@ using HopFrame.Core.Repositories;
namespace HopFrame.Core.Services.Implementations;
-public class RepositoryTableManager(IHopFrameRepository repo, IContextExplorer explorer, IServiceProvider provider) : ITableManager where TModel : class {
+public class RepositoryTableManager(IHopFrameRepository repo, IContextExplorer explorer, IServiceProvider provider, ISearchExpressionBuilder searchExpressionBuilder) : ITableManager where TModel : class {
public async Task> LoadPage(int page, int perPage = 20) {
return await repo.LoadPage(page, perPage);
}
@@ -34,7 +34,7 @@ public class RepositoryTableManager(IHopFrameRepository DisplayProperty(object? item, PropertyConfig prop, object? value = null, object? enumerableValue = null) {
- var manager = new TableManager(null!, null!, explorer, provider);
+ var manager = new TableManager(null!, null!, explorer, provider, searchExpressionBuilder);
return await manager.DisplayProperty(item, prop, value, enumerableValue);
}
}
\ No newline at end of file
diff --git a/src/HopFrame.Core/Services/Implementations/SearchExpressionBuilder.cs b/src/HopFrame.Core/Services/Implementations/SearchExpressionBuilder.cs
new file mode 100644
index 0000000..51978a6
--- /dev/null
+++ b/src/HopFrame.Core/Services/Implementations/SearchExpressionBuilder.cs
@@ -0,0 +1,151 @@
+using System.Linq.Expressions;
+using System.Reflection;
+using HopFrame.Core.Config;
+
+namespace HopFrame.Core.Services.Implementations;
+
+internal sealed class SearchExpressionBuilder(IContextExplorer explorer) : ISearchExpressionBuilder {
+ private readonly struct SearchPart {
+ public string? Property { get; init; }
+ public string Term { get; init; }
+ public bool Negated { get; init; }
+ }
+
+ private Expression AddPropertySearchExpression(PropertyInfo property, ParameterExpression parameter, string searchTerm, PropertyConfig config) {
+ Expression propertyAccess = Expression.Property(parameter, property);
+
+ if (config.IsEnumerable) { //Call Count() extension method before checking the search term
+ propertyAccess = Expression.Property(propertyAccess, config.Info.PropertyType.GetProperty(nameof(List