Skip to content

Commit 5ddb33d

Browse files
authored
fix(Table): add IsAutoInitializeModelProperty parameter control create instance logic (#5530)
* feat: 增加 IsAutoInitializeModelProperty 参数 * chore: bump version 9.4.6 * test: 增加单元测试 * refactor: 更新方法名 * test: 更新单元测试 * test: 更新单元测试 * refactor: 精简代码
1 parent ab8e288 commit 5ddb33d

File tree

5 files changed

+63
-15
lines changed

5 files changed

+63
-15
lines changed

src/BootstrapBlazor/BootstrapBlazor.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk.Razor">
22

33
<PropertyGroup>
4-
<Version>9.4.5</Version>
4+
<Version>9.4.6</Version>
55
</PropertyGroup>
66

77
<ItemGroup>

src/BootstrapBlazor/Components/Table/Table.razor.Edit.cs

+12-2
Original file line numberDiff line numberDiff line change
@@ -294,18 +294,28 @@ private async Task InternalOnAddAsync()
294294
[Parameter]
295295
public Func<TItem>? CreateItemCallback { get; set; }
296296

297+
/// <summary>
298+
/// Get or sets Whether to automatically initialize model properties default value is false.
299+
/// </summary>
300+
[Parameter]
301+
public bool IsAutoInitializeModelProperty { get; set; }
302+
297303
private TItem CreateTItem() => CreateItemCallback?.Invoke() ?? CreateInstance();
298304

305+
private readonly string ErrorMessage = $"{typeof(TItem)} create instrance failed. Please provide {nameof(CreateItemCallback)} create the {typeof(TItem)} instance. {typeof(TItem)} 自动创建实例失败,请通过 {nameof(CreateItemCallback)} 回调方法手动创建实例";
306+
299307
private TItem CreateInstance()
300308
{
309+
TItem? item;
301310
try
302311
{
303-
return ObjectExtensions.CreateInstanceWithCascade<TItem>();
312+
item = ObjectExtensions.CreateInstance<TItem>(IsAutoInitializeModelProperty);
304313
}
305314
catch (Exception ex)
306315
{
307-
throw new InvalidOperationException($"{typeof(TItem)} missing new() method. Please provide {nameof(CreateItemCallback)} create the {typeof(TItem)} instance. {typeof(TItem)} 未提供无参构造函数 new() 请通过 {nameof(CreateItemCallback)} 回调方法创建实例", ex);
316+
throw new InvalidOperationException(ErrorMessage, ex);
308317
}
318+
return item!;
309319
}
310320

311321
/// <summary>

src/BootstrapBlazor/Extensions/ObjectExtensions.cs

+28-12
Original file line numberDiff line numberDiff line change
@@ -242,37 +242,53 @@ internal static void Clone<TModel>(this TModel source, TModel item)
242242
/// Creates an instance of a type and ensures all class-type properties are initialized.
243243
/// </summary>
244244
/// <typeparam name="TItem">The type to create an instance of.</typeparam>
245+
/// <param name="isAutoInitializeModelProperty">Whether to automatically initialize model properties default value is false.</param>
245246
/// <returns>An instance of the specified type with initialized properties.</returns>
246-
public static TItem CreateInstanceWithCascade<TItem>()
247+
public static TItem? CreateInstance<TItem>(bool isAutoInitializeModelProperty = false)
247248
{
248249
var instance = Activator.CreateInstance<TItem>();
249-
instance!.EnsureInitialized();
250+
if (isAutoInitializeModelProperty)
251+
{
252+
instance.EnsureInitialized(isAutoInitializeModelProperty);
253+
}
254+
return instance;
255+
}
256+
257+
private static object? CreateInstance(Type type, bool isAutoInitializeModelProperty = false)
258+
{
259+
var instance = Activator.CreateInstance(type);
260+
if (isAutoInitializeModelProperty)
261+
{
262+
instance.EnsureInitialized();
263+
}
250264
return instance;
251265
}
252266

253267
/// <summary>
254268
/// Ensures that all class-type properties of the instance are initialized.
255269
/// </summary>
270+
/// <param name="isAutoInitializeModelProperty">Whether to automatically initialize model properties default value is false.</param>
256271
/// <param name="instance">The instance to initialize properties for.</param>
257-
private static void EnsureInitialized(this object instance)
272+
private static void EnsureInitialized(this object? instance, bool isAutoInitializeModelProperty = false)
258273
{
274+
if (instance is null)
275+
{
276+
return;
277+
}
278+
259279
// Reflection performance needs to be optimized here
260280
foreach (var propertyInfo in instance.GetType().GetProperties().Where(p => p.PropertyType.IsClass && p.PropertyType != typeof(string)))
261281
{
262282
var type = propertyInfo.PropertyType;
263283
var value = propertyInfo.GetValue(instance, null);
264284
if (value is null)
265285
{
266-
var pv = CreateInstance(type);
267-
propertyInfo.SetValue(instance, pv);
286+
var pv = CreateInstance(type, isAutoInitializeModelProperty);
287+
if (pv is not null)
288+
{
289+
propertyInfo.SetValue(instance, pv);
290+
}
268291
}
269292
}
270293
}
271-
272-
private static object? CreateInstance(Type type)
273-
{
274-
var instance = Activator.CreateInstance(type);
275-
instance!.EnsureInitialized();
276-
return instance;
277-
}
278294
}

test/UnitTest/Components/TableTest.cs

+1
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ public async Task Items_Add(InsertRowMode insertMode, bool bind)
127127
{
128128
pb.AddChildContent<Table<Foo>>(pb =>
129129
{
130+
pb.Add(a => a.IsAutoInitializeModelProperty, true);
130131
pb.Add(a => a.Items, items);
131132
if (bind)
132133
{

test/UnitTest/Extensions/ObjectExtensionsTest.cs

+21
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,27 @@ public void IsStatic_Ok()
303303
Assert.True(pi.IsStatic());
304304
}
305305

306+
[Fact]
307+
public void CreateInstance_Ok()
308+
{
309+
var exception = Assert.ThrowsAny<Exception>(() => ObjectExtensions.CreateInstance<MockComplexObject>(true));
310+
311+
var mi = typeof(ObjectExtensions).GetMethod("EnsureInitialized", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic);
312+
Assert.NotNull(mi);
313+
mi.Invoke(null, [null, false]);
314+
315+
var instance = ObjectExtensions.CreateInstance<MockComplexObject>(false);
316+
Assert.NotNull(instance);
317+
Assert.Null(instance.Test);
318+
}
319+
320+
private class MockComplexObject
321+
{
322+
public Foo? Foo { get; set; }
323+
324+
public (string Name, int Count)[]? Test { get; set; }
325+
}
326+
306327
private class MockStatic
307328
{
308329
private static int _test;

0 commit comments

Comments
 (0)