Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move WeakEventManager to Core.csproj #5139

Merged
merged 10 commits into from
Mar 21, 2022
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<Type Name="WeakEventManager" FullName="Microsoft.Maui.Controls.WeakEventManager">
<Type Name="WeakEventManager" FullName="Microsoft.Maui.WeakEventManager">
<TypeSignature Language="C#" Value="public class WeakEventManager" />
<TypeSignature Language="ILAsm" Value=".class public auto ansi beforefieldinit WeakEventManager extends System.Object" />
<TypeSignature Language="DocId" Value="T:Microsoft.Maui.Controls.WeakEventManager" />
<TypeSignature Language="DocId" Value="T:Microsoft.Maui.WeakEventManager" />
<TypeSignature Language="F#" Value="type WeakEventManager = class" />
<AssemblyInfo>
<AssemblyName>Microsoft.Maui.Controls.Core</AssemblyName>
<AssemblyName>Microsoft.Maui.Core</AssemblyName>
<AssemblyVersion>2.0.0.0</AssemblyVersion>
</AssemblyInfo>
<Base>
Expand All @@ -19,10 +19,10 @@
<Member MemberName=".ctor">
<MemberSignature Language="C#" Value="public WeakEventManager ();" />
<MemberSignature Language="ILAsm" Value=".method public hidebysig specialname rtspecialname instance void .ctor() cil managed" />
<MemberSignature Language="DocId" Value="M:Microsoft.Maui.Controls.WeakEventManager.#ctor" />
<MemberSignature Language="DocId" Value="M:Microsoft.Maui.WeakEventManager.#ctor" />
<MemberType>Constructor</MemberType>
<AssemblyInfo>
<AssemblyName>Microsoft.Maui.Controls.Core</AssemblyName>
<AssemblyName>Microsoft.Maui.Core</AssemblyName>
<AssemblyVersion>2.0.0.0</AssemblyVersion>
</AssemblyInfo>
<Parameters />
Expand All @@ -34,11 +34,11 @@
<Member MemberName="AddEventHandler">
<MemberSignature Language="C#" Value="public void AddEventHandler (EventHandler handler, string eventName = default);" />
<MemberSignature Language="ILAsm" Value=".method public hidebysig instance void AddEventHandler(class System.EventHandler handler, string eventName) cil managed" />
<MemberSignature Language="DocId" Value="M:Microsoft.Maui.Controls.WeakEventManager.AddEventHandler(System.EventHandler,System.String)" />
<MemberSignature Language="DocId" Value="M:Microsoft.Maui.WeakEventManager.AddEventHandler(System.EventHandler,System.String)" />
<MemberSignature Language="F#" Value="member this.AddEventHandler : EventHandler * string -&gt; unit" Usage="weakEventManager.AddEventHandler (handler, eventName)" />
<MemberType>Method</MemberType>
<AssemblyInfo>
<AssemblyName>Microsoft.Maui.Controls.Core</AssemblyName>
<AssemblyName>Microsoft.Maui.Core</AssemblyName>
<AssemblyVersion>2.0.0.0</AssemblyVersion>
</AssemblyInfo>
<ReturnValue>
Expand All @@ -64,11 +64,11 @@
<Member MemberName="AddEventHandler&lt;TEventArgs&gt;">
<MemberSignature Language="C#" Value="public void AddEventHandler&lt;TEventArgs&gt; (EventHandler&lt;TEventArgs&gt; handler, string eventName = default) where TEventArgs : EventArgs;" />
<MemberSignature Language="ILAsm" Value=".method public hidebysig instance void AddEventHandler&lt;(class System.EventArgs) TEventArgs&gt;(class System.EventHandler`1&lt;!!TEventArgs&gt; handler, string eventName) cil managed" />
<MemberSignature Language="DocId" Value="M:Microsoft.Maui.Controls.WeakEventManager.AddEventHandler``1(System.EventHandler{``0},System.String)" />
<MemberSignature Language="DocId" Value="M:Microsoft.Maui.WeakEventManager.AddEventHandler``1(System.EventHandler{``0},System.String)" />
<MemberSignature Language="F#" Value="member this.AddEventHandler : EventHandler&lt;'EventArgs (requires 'EventArgs :&gt; EventArgs)&gt; * string -&gt; unit (requires 'EventArgs :&gt; EventArgs)" Usage="weakEventManager.AddEventHandler (handler, eventName)" />
<MemberType>Method</MemberType>
<AssemblyInfo>
<AssemblyName>Microsoft.Maui.Controls.Core</AssemblyName>
<AssemblyName>Microsoft.Maui.Core</AssemblyName>
<AssemblyVersion>2.0.0.0</AssemblyVersion>
</AssemblyInfo>
<ReturnValue>
Expand Down Expand Up @@ -102,11 +102,11 @@
<Member MemberName="HandleEvent">
<MemberSignature Language="C#" Value="public void HandleEvent (object sender, object args, string eventName);" />
<MemberSignature Language="ILAsm" Value=".method public hidebysig instance void HandleEvent(object sender, object args, string eventName) cil managed" />
<MemberSignature Language="DocId" Value="M:Microsoft.Maui.Controls.WeakEventManager.HandleEvent(System.Object,System.Object,System.String)" />
<MemberSignature Language="DocId" Value="M:Microsoft.Maui.WeakEventManager.HandleEvent(System.Object,System.Object,System.String)" />
<MemberSignature Language="F#" Value="member this.HandleEvent : obj * obj * string -&gt; unit" Usage="weakEventManager.HandleEvent (sender, args, eventName)" />
<MemberType>Method</MemberType>
<AssemblyInfo>
<AssemblyName>Microsoft.Maui.Controls.Core</AssemblyName>
<AssemblyName>Microsoft.Maui.Core</AssemblyName>
<AssemblyVersion>2.0.0.0</AssemblyVersion>
</AssemblyInfo>
<ReturnValue>
Expand All @@ -128,11 +128,11 @@
<Member MemberName="RemoveEventHandler">
<MemberSignature Language="C#" Value="public void RemoveEventHandler (EventHandler handler, string eventName = default);" />
<MemberSignature Language="ILAsm" Value=".method public hidebysig instance void RemoveEventHandler(class System.EventHandler handler, string eventName) cil managed" />
<MemberSignature Language="DocId" Value="M:Microsoft.Maui.Controls.WeakEventManager.RemoveEventHandler(System.EventHandler,System.String)" />
<MemberSignature Language="DocId" Value="M:Microsoft.Maui.WeakEventManager.RemoveEventHandler(System.EventHandler,System.String)" />
<MemberSignature Language="F#" Value="member this.RemoveEventHandler : EventHandler * string -&gt; unit" Usage="weakEventManager.RemoveEventHandler (handler, eventName)" />
<MemberType>Method</MemberType>
<AssemblyInfo>
<AssemblyName>Microsoft.Maui.Controls.Core</AssemblyName>
<AssemblyName>Microsoft.Maui.Core</AssemblyName>
<AssemblyVersion>2.0.0.0</AssemblyVersion>
</AssemblyInfo>
<ReturnValue>
Expand All @@ -158,11 +158,11 @@
<Member MemberName="RemoveEventHandler&lt;TEventArgs&gt;">
<MemberSignature Language="C#" Value="public void RemoveEventHandler&lt;TEventArgs&gt; (EventHandler&lt;TEventArgs&gt; handler, string eventName = default) where TEventArgs : EventArgs;" />
<MemberSignature Language="ILAsm" Value=".method public hidebysig instance void RemoveEventHandler&lt;(class System.EventArgs) TEventArgs&gt;(class System.EventHandler`1&lt;!!TEventArgs&gt; handler, string eventName) cil managed" />
<MemberSignature Language="DocId" Value="M:Microsoft.Maui.Controls.WeakEventManager.RemoveEventHandler``1(System.EventHandler{``0},System.String)" />
<MemberSignature Language="DocId" Value="M:Microsoft.Maui.WeakEventManager.RemoveEventHandler``1(System.EventHandler{``0},System.String)" />
<MemberSignature Language="F#" Value="member this.RemoveEventHandler : EventHandler&lt;'EventArgs (requires 'EventArgs :&gt; EventArgs)&gt; * string -&gt; unit (requires 'EventArgs :&gt; EventArgs)" Usage="weakEventManager.RemoveEventHandler (handler, eventName)" />
<MemberType>Method</MemberType>
<AssemblyInfo>
<AssemblyName>Microsoft.Maui.Controls.Core</AssemblyName>
<AssemblyName>Microsoft.Maui.Core</AssemblyName>
<AssemblyVersion>2.0.0.0</AssemblyVersion>
</AssemblyInfo>
<ReturnValue>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@
using System.Runtime.CompilerServices;

using static System.String;
namespace Microsoft.Maui.Controls
namespace Microsoft.Maui
{
/// <include file="../../docs/Microsoft.Maui.Controls/WeakEventManager.xml" path="Type[@FullName='Microsoft.Maui.Controls.WeakEventManager']/Docs" />
/// <include file="../../docs/Microsoft.Maui/WeakEventManager.xml" path="Type[@FullName='Microsoft.Maui.WeakEventManager']/Docs" />
public class WeakEventManager
{
readonly Dictionary<string, List<Subscription>> _eventHandlers = new Dictionary<string, List<Subscription>>();

/// <include file="../../docs/Microsoft.Maui.Controls/WeakEventManager.xml" path="//Member[@MemberName='AddEventHandler']/Docs" />
/// <include file="../../docs/Microsoft.Maui/WeakEventManager.xml" path="//Member[@MemberName='AddEventHandler']/Docs" />
public void AddEventHandler<TEventArgs>(EventHandler<TEventArgs> handler, [CallerMemberName] string eventName = "")
where TEventArgs : EventArgs
{
Expand All @@ -25,7 +25,7 @@ public void AddEventHandler<TEventArgs>(EventHandler<TEventArgs> handler, [Calle
AddEventHandler(eventName, handler.Target, handler.GetMethodInfo());
}

/// <include file="../../docs/Microsoft.Maui.Controls/WeakEventManager.xml" path="//Member[@MemberName='AddEventHandler']/Docs" />
/// <include file="../../docs/Microsoft.Maui/WeakEventManager.xml" path="//Member[@MemberName='AddEventHandler']/Docs" />
public void AddEventHandler(Delegate? handler, [CallerMemberName] string eventName = "")
{
if (IsNullOrEmpty(eventName))
Expand All @@ -37,7 +37,7 @@ public void AddEventHandler(Delegate? handler, [CallerMemberName] string eventNa
AddEventHandler(eventName, handler.Target, handler.GetMethodInfo());
}

/// <include file="../../docs/Microsoft.Maui.Controls/WeakEventManager.xml" path="//Member[@MemberName='HandleEvent']/Docs" />
/// <include file="../../docs/Microsoft.Maui/WeakEventManager.xml" path="//Member[@MemberName='HandleEvent']/Docs" />
public void HandleEvent(object sender, object args, string eventName)
{
var toRaise = new List<(object? subscriber, MethodInfo handler)>();
Expand Down Expand Up @@ -79,7 +79,7 @@ public void HandleEvent(object sender, object args, string eventName)
}
}

/// <include file="../../docs/Microsoft.Maui.Controls/WeakEventManager.xml" path="//Member[@MemberName='RemoveEventHandler']/Docs" />
/// <include file="../../docs/Microsoft.Maui/WeakEventManager.xml" path="//Member[@MemberName='RemoveEventHandler']/Docs" />
public void RemoveEventHandler<TEventArgs>(EventHandler<TEventArgs> handler, [CallerMemberName] string eventName = "")
where TEventArgs : EventArgs
{
Expand All @@ -92,7 +92,7 @@ public void RemoveEventHandler<TEventArgs>(EventHandler<TEventArgs> handler, [Ca
RemoveEventHandler(eventName, handler.Target, handler.GetMethodInfo());
}

/// <include file="../../docs/Microsoft.Maui.Controls/WeakEventManager.xml" path="//Member[@MemberName='RemoveEventHandler']/Docs" />
/// <include file="../../docs/Microsoft.Maui/WeakEventManager.xml" path="//Member[@MemberName='RemoveEventHandler']/Docs" />
public void RemoveEventHandler(Delegate? handler, [CallerMemberName] string eventName = "")
{
if (IsNullOrEmpty(eventName))
Expand Down Expand Up @@ -141,16 +141,16 @@ void RemoveEventHandler(string eventName, object? handlerTarget, MemberInfo meth

struct Subscription
{
/// <include file="../../docs/Microsoft.Maui.Controls/WeakEventManager.xml" path="//Member[@MemberName='.ctor']/Docs" />
/// <include file="../../docs/Microsoft.Maui/WeakEventManager.xml" path="//Member[@MemberName='.ctor']/Docs" />
public Subscription(WeakReference? subscriber, MethodInfo handler)
{
Subscriber = subscriber;
Handler = handler ?? throw new ArgumentNullException(nameof(handler));
}

/// <include file="../../docs/Microsoft.Maui.Controls/WeakEventManager.xml" path="//Member[@MemberName='Subscriber']/Docs" />
/// <include file="../../docs/Microsoft.Maui/WeakEventManager.xml" path="//Member[@MemberName='Subscriber']/Docs" />
public readonly WeakReference? Subscriber;
/// <include file="../../docs/Microsoft.Maui.Controls/WeakEventManager.xml" path="//Member[@MemberName='Handler']/Docs" />
/// <include file="../../docs/Microsoft.Maui/WeakEventManager.xml" path="//Member[@MemberName='Handler']/Docs" />
public readonly MethodInfo Handler;
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
#nullable enable
using System;
using System.ComponentModel;
using NUnit.Framework;
using Xunit;

namespace Microsoft.Maui.Controls.Core.UnitTests
namespace Microsoft.Maui.UnitTests
{
[TestFixture]
public class WeakEventManagerTests : INotifyPropertyChanged
{
static int s_count;
Expand Down Expand Up @@ -77,7 +76,7 @@ public void Subscribe(TestEventSource source)

void SourceOnTestEvent(object? sender, EventArgs eventArgs)
{
Assert.Fail();
throw new Exception("Fail");
}
}

Expand All @@ -87,21 +86,21 @@ public event PropertyChangedEventHandler? PropertyChanged
remove => _propertyChangedWeakEventManager.RemoveEventHandler(value);
}

[Test]
[Fact]
public void AddHandlerWithEmptyEventNameThrowsException()
{
var wem = new WeakEventManager();
Assert.Throws<ArgumentNullException>(() => wem.AddEventHandler((EventHandler)((sender, args) => { }), ""));
}

[Test]
[Fact]
public void AddHandlerWithNullEventHandlerThrowsException()
{
var wem = new WeakEventManager();
Assert.Throws<ArgumentNullException>(() => wem.AddEventHandler(null, "test"));
}

[Test]
[Fact]
public void AddHandlerWithNullEventNameThrowsException()
{
var wem = new WeakEventManager();
Expand All @@ -110,20 +109,20 @@ public void AddHandlerWithNullEventNameThrowsException()
#pragma warning restore CS8625 // Cannot convert null literal to non-nullable reference type.
}

[Test]
[Fact]
public void CanRemoveEventHandler()
{
var source = new TestSource();
int beforeRun = source.Count;
source.Fire();

Assert.IsTrue(source.Count == 1);
Assert.True(source.Count == 1);
source.Clean();
source.Fire();
Assert.IsTrue(source.Count == 1);
Assert.True(source.Count == 1);
}

[Test]
[Fact]
public void CanRemoveStaticEventHandler()
{
int beforeRun = s_count;
Expand All @@ -134,10 +133,10 @@ public void CanRemoveStaticEventHandler()

source.FireTestEvent();

Assert.IsTrue(s_count == beforeRun);
Assert.True(s_count == beforeRun);
}

[Test]
[Fact]
public void EventHandlerCalled()
{
var called = false;
Expand All @@ -147,17 +146,17 @@ public void EventHandlerCalled()

source.FireTestEvent();

Assert.IsTrue(called);
Assert.True(called);
}

[Test]
[Fact]
public void FiringEventWithoutHandlerShouldNotThrow()
{
var source = new TestEventSource();
source.FireTestEvent();
}

[Test]
[Fact]
public void MultipleHandlersCalled()
{
var called1 = false;
Expand All @@ -168,24 +167,24 @@ public void MultipleHandlersCalled()
source.TestEvent += (sender, args) => { called2 = true; };
source.FireTestEvent();

Assert.IsTrue(called1 && called2);
Assert.True(called1 && called2);
}

[Test]
[Fact]
public void RemoveHandlerWithEmptyEventNameThrowsException()
{
var wem = new WeakEventManager();
Assert.Throws<ArgumentNullException>(() => wem.RemoveEventHandler((EventHandler)((sender, args) => { }), ""));
}

[Test]
[Fact]
public void RemoveHandlerWithNullEventHandlerThrowsException()
{
var wem = new WeakEventManager();
Assert.Throws<ArgumentNullException>(() => wem.RemoveEventHandler(null, "test"));
}

[Test]
[Fact]
public void RemoveHandlerWithNullEventNameThrowsException()
{
var wem = new WeakEventManager();
Expand All @@ -194,15 +193,15 @@ public void RemoveHandlerWithNullEventNameThrowsException()
#pragma warning restore CS8625 // Cannot convert null literal to non-nullable reference type.
}

[Test]
[Fact]
public void RemovingNonExistentHandlersShouldNotThrow()
{
var wem = new WeakEventManager();
wem.RemoveEventHandler((EventHandler)((sender, args) => { }), "fake");
wem.RemoveEventHandler((Action<object?, EventArgs>)Handler, "alsofake");
}

[Test]
[Fact]
public void RemoveHandlerWithMultipleSubscriptionsRemovesOne()
{
int beforeRun = s_count;
Expand All @@ -214,10 +213,10 @@ public void RemoveHandlerWithMultipleSubscriptionsRemovesOne()

source.FireTestEvent();

Assert.AreEqual(beforeRun + 1, s_count);
Assert.Equal(beforeRun + 1, s_count);
}

[Test]
[Fact]
public void StaticHandlerShouldRun()
{
int beforeRun = s_count;
Expand All @@ -227,10 +226,10 @@ public void StaticHandlerShouldRun()

source.FireTestEvent();

Assert.IsTrue(s_count > beforeRun);
Assert.True(s_count > beforeRun);
}

[Test]
[Fact]
public void VerifySubscriberCanBeCollected()
{
WeakReference? wr = null;
Expand All @@ -245,15 +244,15 @@ public void VerifySubscriberCanBeCollected()
GC.Collect();
GC.WaitForPendingFinalizers();

Assert.IsNotNull(wr);
Assert.IsFalse(wr?.IsAlive);
Assert.NotNull(wr);
Assert.False(wr?.IsAlive);

// The handler for this calls Assert.Fail, so if the subscriber has not been collected
// the handler will be called and the test will fail
source.FireTestEvent();
}

[Test]
[Fact]
public void VerifyPropertyChanged()
{
//Arrange
Expand All @@ -262,10 +261,10 @@ public void VerifyPropertyChanged()

void HandleDelegateTest(object? sender, PropertyChangedEventArgs e)
{
Assert.IsNotNull(sender);
Assert.AreEqual(this.GetType(), sender?.GetType());
Assert.NotNull(sender);
Assert.Equal(this.GetType(), sender?.GetType());

Assert.IsNotNull(e);
Assert.NotNull(e);

didEventFire = true;
PropertyChanged -= HandleDelegateTest;
Expand All @@ -275,7 +274,7 @@ void HandleDelegateTest(object? sender, PropertyChangedEventArgs e)
_propertyChangedWeakEventManager.HandleEvent(this, new PropertyChangedEventArgs("Test"), nameof(PropertyChanged));

//Assert
Assert.IsTrue(didEventFire);
Assert.True(didEventFire);
}
}
}