From 2151a19bdbdeb2896ac02029eb70b32d82fa4df9 Mon Sep 17 00:00:00 2001 From: Freelancingonupwork <56026691+Freelancingonupwork@users.noreply.github.com> Date: Thu, 30 May 2024 09:28:32 +0530 Subject: [PATCH] Added AddNewAsync() methods to lists with AddNew which are using IObservableBindingList (#3989) Co-authored-by: Rockford Lhotka --- .../BusinessListBase/AddNewAsyncTests.cs | 75 +++++++++++++++++++ Source/Csla/BusinessListBase.cs | 12 +++ Source/Csla/Core/IObservableBindingList.cs | 4 + Source/Csla/Core/ObservableBindingList.cs | 43 +++++++++++ Source/Csla/DynamicListBase.cs | 12 +++ 5 files changed, 146 insertions(+) create mode 100644 Source/Csla.test/BusinessListBase/AddNewAsyncTests.cs diff --git a/Source/Csla.test/BusinessListBase/AddNewAsyncTests.cs b/Source/Csla.test/BusinessListBase/AddNewAsyncTests.cs new file mode 100644 index 0000000000..ed2e462583 --- /dev/null +++ b/Source/Csla.test/BusinessListBase/AddNewAsyncTests.cs @@ -0,0 +1,75 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Marimer LLC. All rights reserved. +// Website: https://cslanet.com +// +// no summary +//----------------------------------------------------------------------- + +using Csla.TestHelpers; +using FluentAssertions; +using FluentAssertions.Execution; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace Csla.Test.BusinessListBase +{ + [TestClass] + public class AddNewAsyncTests + { + private static TestDIContext _testDIContext; + + [ClassInitialize] + public static void ClassInitialize(TestContext context) + { + _testDIContext = TestDIContextFactory.CreateDefaultContext(); + } + + [TestMethod] + public async Task RootAddNewCoreAsync() + { + bool changed = false; + var obj = CreateRootList(); + obj.CollectionChanged += (_, _) => + { + changed = true; + }; + var child = await obj.AddNewAsync(); + Assert.IsTrue(changed); + Assert.AreEqual(child, obj[0]); + } + + [TestMethod] + public async Task ChildAddNewCoreAsync() + { + bool childChanged = false; + bool changed = false; + var obj = CreateRoot(); + obj.ChildChanged += (_, _) => + { + childChanged = true; + }; + obj.Children.CollectionChanged += (_, _) => + { + changed = true; + }; + var child = await obj.Children.AddNewAsync(); + Assert.IsTrue(childChanged, "ChildChanged should be true"); + Assert.IsTrue(changed, "Collection changed should be true"); + Assert.AreEqual(child, obj.Children[0]); + } + + private Root CreateRoot() + { + IDataPortal dataPortal = _testDIContext.CreateDataPortal(); + + return dataPortal.Create(); + } + + private RootList CreateRootList() + { + IDataPortal dataPortal = _testDIContext.CreateDataPortal(); + + return dataPortal.Create(); + } + } +} \ No newline at end of file diff --git a/Source/Csla/BusinessListBase.cs b/Source/Csla/BusinessListBase.cs index a48b16960d..350e8d7138 100644 --- a/Source/Csla/BusinessListBase.cs +++ b/Source/Csla/BusinessListBase.cs @@ -308,6 +308,18 @@ protected override C AddNewCore() return item; } + /// + /// Override this method to create a new object that is added + /// to the collection. + /// + protected override async Task AddNewCoreAsync() + { + var dp = ApplicationContext.CreateInstanceDI>(); + var item = await dp.CreateChildAsync(); + Add(item); + return item; + } + /// /// This method is called by a child object when it /// wants to be removed from the collection. diff --git a/Source/Csla/Core/IObservableBindingList.cs b/Source/Csla/Core/IObservableBindingList.cs index 1e2b5693e4..579289bc98 100644 --- a/Source/Csla/Core/IObservableBindingList.cs +++ b/Source/Csla/Core/IObservableBindingList.cs @@ -24,5 +24,9 @@ public interface IObservableBindingList /// removed from the list. /// event EventHandler RemovingItem; + /// + /// Creates and adds a new item to the collection. + /// + Task AddNewAsync(); } } \ No newline at end of file diff --git a/Source/Csla/Core/ObservableBindingList.cs b/Source/Csla/Core/ObservableBindingList.cs index ec2cd3e803..8671be71ec 100644 --- a/Source/Csla/Core/ObservableBindingList.cs +++ b/Source/Csla/Core/ObservableBindingList.cs @@ -96,6 +96,21 @@ object IObservableBindingList.AddNew() return AddNew(); } + /// + /// Adds a new item to this collection. + /// + public async Task AddNewAsync() + { + var result = await AddNewCoreAsync(); + await OnAddedNewAsync(result); + return result; + } + + async Task IObservableBindingList.AddNewAsync() + { + return await AddNewAsync(); + } + #endregion #region RemovingItem event @@ -493,6 +508,25 @@ public virtual void OnAddedNew(T item) } } + /// + /// Raises the AddedNew event. + /// + /// + [EditorBrowsable(EditorBrowsableState.Advanced)] + public async virtual Task OnAddedNewAsync(T item) + { + if (_addedNewHandlers != null) + { + var args = new AddedNewEventArgs(item); + var handlerTasks = _addedNewHandlers + .GetInvocationList() + .Cast>>() + .Select(handler => Task.Run(() => handler(this, args))); + + await Task.WhenAll(handlerTasks); + } + } + #if ANDROID || IOS /// /// Override this method to create a new object that is added @@ -511,6 +545,15 @@ protected virtual T AddNewCore() { throw new NotImplementedException(Resources.AddNewCoreMustBeOverriden); } + + /// + /// Override this method to create a new object that is added + /// to the collection. + /// + protected virtual async Task AddNewCoreAsync() + { + return await Task.FromException(new NotImplementedException(Resources.AddNewCoreMustBeOverriden)); + } #endif #endregion diff --git a/Source/Csla/DynamicListBase.cs b/Source/Csla/DynamicListBase.cs index 86a3324794..2be58cd44a 100644 --- a/Source/Csla/DynamicListBase.cs +++ b/Source/Csla/DynamicListBase.cs @@ -311,6 +311,18 @@ protected override T AddNewCore() return item; } + /// + /// Adds a new item to the list. + /// + /// The added object + protected override async Task AddNewCoreAsync() + { + var dp = ApplicationContext.CreateInstanceDI>(); + T item = await dp.CreateAsync(); + Add(item); + return item; + } + /// /// Gives the new object a parent reference to this /// list.