Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 16 additions & 18 deletions src/BootstrapBlazor/Dynamic/DataTableDynamicContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,35 +75,33 @@
{
DataTable = table;
AddAttributesCallback = addAttributesCallback;
OnValueChanged = OnCellValueChanged;

// 获得 DataTable 列信息转换为 ITableColumn 集合
var cols = InternalGetColumns();

// Emit 生成动态类
DynamicObjectType = CreateType();
// Emit 生成动态类 (使用缓存)
var columnNames = string.Join('|', cols.Select(static c => $"{c.GetFieldName}:{c.PropertyType.FullName}"));
var cacheKey = $"BootstrapBlazor-{nameof(DataTableDynamicContext)}-{columnNames}";
var dynamicType = CacheManager.GetOrCreateDynamicObjectTypeByName(cacheKey, cols, OnColumnCreating, out var cached);

Check failure on line 86 in src/BootstrapBlazor/Dynamic/DataTableDynamicContext.cs

View workflow job for this annotation

GitHub Actions / run test

'CacheManager' does not contain a definition for 'GetOrCreateDynamicObjectTypeByName'
Comment thread
ArgoZhang marked this conversation as resolved.
Outdated

// 缓存命中时仍需调用回调以处理列属性
if (!cached && AddAttributesCallback != null)
{
foreach (var col in cols)
{
AddAttributesCallback(this, col);

Check warning on line 93 in src/BootstrapBlazor/Dynamic/DataTableDynamicContext.cs

View workflow job for this annotation

GitHub Actions / run test

Dereference of a possibly null reference.
}
}
Comment thread
ArgoZhang marked this conversation as resolved.
Outdated
DynamicObjectType = GetOrCreateType();

Check failure on line 96 in src/BootstrapBlazor/Dynamic/DataTableDynamicContext.cs

View workflow job for this annotation

GitHub Actions / run test

The name 'GetOrCreateType' does not exist in the current context

// 获得显示列
Columns = Utility.GetTableColumns(DynamicObjectType, cols).Where(col => GetShownColumns(col, invisibleColumns, shownColumns, hiddenColumns));

OnValueChanged = OnCellValueChanged;

[ExcludeFromCodeCoverage]
Type CreateType()

Check warning on line 102 in src/BootstrapBlazor/Dynamic/DataTableDynamicContext.cs

View workflow job for this annotation

GitHub Actions / run test

The local function 'CreateType' is declared but never used
{
// Emit 生成动态类 (使用缓存)
var columnNames = string.Join('|', table.Columns.Cast<DataColumn>().Select(static c => $"{c.ColumnName}:{c.DataType.FullName}"));
var cacheKey = $"BootstrapBlazor-{nameof(DataTableDynamicContext)}-{columnNames}";
var dynamicType = CacheManager.GetDynamicObjectTypeByName(cacheKey, cols, OnColumnCreating, out var cached);

// 缓存命中时仍需调用回调以处理列属性
if (cached && AddAttributesCallback != null)
{
foreach (var col in cols)
{
AddAttributesCallback?.Invoke(this, col);
}
}

var dynamicType = EmitHelper.CreateTypeByName($"BootstrapBlazor_{nameof(DataTableDynamicContext)}_{GetHashCode()}", cols, typeof(DataTableDynamicObject), OnColumnCreating);
Comment thread
ArgoZhang marked this conversation as resolved.
Outdated
return dynamicType ?? throw new InvalidOperationException();
}
Comment thread
ArgoZhang marked this conversation as resolved.
Outdated
}
Expand Down
15 changes: 0 additions & 15 deletions src/BootstrapBlazor/Services/CacheManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
using System.Globalization;
using System.Linq.Expressions;
using System.Reflection;
using System.Reflection.Emit;

#if NET8_0_OR_GREATER
using System.Runtime.CompilerServices;
Expand Down Expand Up @@ -765,18 +764,4 @@ public static object GetFormatterInvoker(Type type, Func<object, Task<string?>>

private static Func<TType, Task<string?>> InvokeFormatterAsync<TType>(Func<object?, Task<string?>> formatter) => new(v => formatter(v));
#endregion

internal static Type? GetDynamicObjectTypeByName(string key, IEnumerable<ITableColumn> cols, Func<ITableColumn, IEnumerable<CustomAttributeBuilder>>? creatingCallback, out bool cached)
{
var created = false;
var type = Instance.GetOrCreate(key, _ =>
{
created = true;
return EmitHelper.CreateTypeByName($"BootstrapBlazor_{nameof(DataTableDynamicContext)}_{key}", cols, typeof(DataTableDynamicObject), creatingCallback);
});

// 是否从缓存中获取到的值
cached = !created;
return type;
}
}
25 changes: 16 additions & 9 deletions src/BootstrapBlazor/Utils/EmitHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,24 +33,31 @@ public static class EmitHelper
/// </param>
public static Type? CreateTypeByName(string typeName, IEnumerable<ITableColumn> cols, Type? parent = null, Func<ITableColumn, IEnumerable<CustomAttributeBuilder>>? creatingCallback = null)
{
var typeBuilder = CreateTypeBuilderByName(typeName, parent);
var moduleBuilder = _moduleBuilderLazy.Value;
var type = moduleBuilder.GetType(typeName);
if (type != null)
{
return type;
}

foreach (var col in cols)
var typeBuilder = moduleBuilder.DefineType(typeName, TypeAttributes.Public, parent);
Comment thread
sourcery-ai[bot] marked this conversation as resolved.
Outdated
if (creatingCallback != null)
Comment thread
ArgoZhang marked this conversation as resolved.
Outdated
{
var attributeBuilds = creatingCallback?.Invoke(col);
typeBuilder.CreateProperty(col, attributeBuilds);
foreach (var col in cols)
{
var attributeBuilds = creatingCallback(col);
typeBuilder.CreateProperty(col, attributeBuilds);
}
}
Comment thread
ArgoZhang marked this conversation as resolved.
Outdated
return typeBuilder.CreateType();
}

private static TypeBuilder CreateTypeBuilderByName(string typeName, Type? parent = null)
private static Lazy<ModuleBuilder> _moduleBuilderLazy = new Lazy<ModuleBuilder>(() =>
{
var assemblyName = new AssemblyName("BootstrapBlazor_DynamicAssembly");
var assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndCollect);
Comment thread
ArgoZhang marked this conversation as resolved.
var moduleBuilder = assemblyBuilder.DefineDynamicModule("BootstrapBlazor_DynamicAssembly_Module");
var typeBuilder = moduleBuilder.DefineType(typeName, TypeAttributes.Public, parent);
return typeBuilder;
}
return assemblyBuilder.DefineDynamicModule("BootstrapBlazor_DynamicAssembly_Module");
});

private static void CreateProperty(this TypeBuilder typeBuilder, IEditorItem col, IEnumerable<CustomAttributeBuilder>? attributeBuilds = null) => CreateProperty(typeBuilder, col.GetFieldName(), col.PropertyType, attributeBuilds);

Expand Down
Loading