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

Add 'AddOrReplace' to IRegionBehaviorFactory #3169

Merged
merged 4 commits into from
Jul 19, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
7 changes: 7 additions & 0 deletions src/Prism.Core/Navigation/Regions/IRegionBehaviorFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@ public interface IRegionBehaviorFactory : IEnumerable<string>
/// <param name="behaviorType">Type of the behavior to add.</param>
void AddIfMissing(string behaviorKey, Type behaviorType);

/// <summary>
/// Adds or replaces a particular type of RegionBehavior. the <paramref name="behaviorKey"/> string is used to check if the behavior is already present
/// </summary>
/// <param name="behaviorKey">The behavior key that's used to find if a certain behavior is already added.</param>
/// <param name="behaviorType">Type of the behavior to add.</param>
void AddOrReplace(string behaviorKey, Type behaviorType);

/// <summary>
/// Determines whether a behavior with the specified key already exists
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace Prism.Navigation.Regions
namespace Prism.Navigation.Regions
{
/// <summary>
/// Extension methods for the IRegionBehaviorFactory.
Expand All @@ -16,6 +16,17 @@ public static void AddIfMissing<T>(this IRegionBehaviorFactory regionBehaviorFac
regionBehaviorFactory.AddIfMissing(typeof(T).Name, behaviorType);
}

/// <summary>
/// Adds or replaces a particular type of RegionBehavior. the Type Name is used to check if the behavior is already present
/// </summary>
/// <typeparam name="T">Type of the behavior to add.</typeparam>
/// <param name="regionBehaviorFactory">The IRegionBehaviorFactory instance</param>
public static void AddOrReplace<T>(this IRegionBehaviorFactory regionBehaviorFactory) where T : IRegionBehavior
{
var behaviorType = typeof(T);
regionBehaviorFactory.AddOrReplace(typeof(T).Name, behaviorType);
}

/// <summary>
/// Adds a particular type of RegionBehavior if it was not already registered. the <paramref name="behaviorKey"/> string is used to check if the behavior is already present
/// </summary>
Expand All @@ -27,5 +38,17 @@ public static void AddIfMissing<T>(this IRegionBehaviorFactory regionBehaviorFac
var behaviorType = typeof(T);
regionBehaviorFactory.AddIfMissing(behaviorKey, behaviorType);
}

/// <summary>
/// Adds or replaces a particular type of RegionBehavior. the <paramref name="behaviorKey"/> string is used to check if the behavior is already present
/// </summary>
/// <typeparam name="T">Type of the behavior to add.</typeparam>
/// <param name="regionBehaviorFactory">The IRegionBehaviorFactory instance</param>
/// <param name="behaviorKey">The behavior key that's used to find if a certain behavior is already added.</param>
public static void AddOrReplace<T>(this IRegionBehaviorFactory regionBehaviorFactory, string behaviorKey) where T : IRegionBehavior
{
var behaviorType = typeof(T);
regionBehaviorFactory.AddOrReplace(behaviorKey, behaviorType);
}
}
}
16 changes: 16 additions & 0 deletions src/Prism.Core/Navigation/Regions/RegionBehaviorFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,22 @@ public void AddIfMissing(string behaviorKey, Type behaviorType)
_registeredBehaviors.Add(behaviorKey, behaviorType);
}

/// <summary>
/// Adds or replaces a particular type of RegionBehavior. The <paramref name="behaviorKey"/> string is used to check if the behavior is already present
/// </summary>
/// <param name="behaviorKey">The behavior key that's used to find if a certain behavior is already added.</param>
/// <param name="behaviorType">Type of the behavior to add.</param>
public void AddOrReplace(string behaviorKey, Type behaviorType)
{
if (_registeredBehaviors.ContainsKey(behaviorKey)
&& _registeredBehaviors[behaviorKey].Equals(behaviorType) == false)
{
_registeredBehaviors.Remove(behaviorKey);
}

AddIfMissing(behaviorKey, behaviorType);
}

/// <summary>
/// Creates an instance of the behavior <see cref="Type"/> that is registered using the specified key.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
using Prism.DryIoc.Maui.Tests.Mocks.Regions.Behaviors;
using Prism.Navigation.Regions.Behaviors;

namespace Prism.DryIoc.Maui.Tests.Fixtures.Regions;
public class RegionBehaviorFixture : TestBase
{
public RegionBehaviorFixture(ITestOutputHelper testOutputHelper)
: base(testOutputHelper)
{
}

[Fact]
public void ExistingBehavior_IsReplaced_WithCustomBehavior()
{
var mauiApp = CreateBuilder(prism => prism
.ConfigureRegionBehaviors(behaviors =>
{
behaviors.AddOrReplace<RegionBehaviorBMock>(RegionBehaviorAMock.BehaviorKey);
}))
.Build();

var regionBehaviorFactory = mauiApp.Services.GetRequiredService<IRegionBehaviorFactory>();

Assert.NotEmpty(regionBehaviorFactory);
Assert.Contains(regionBehaviorFactory, x => x == RegionBehaviorAMock.BehaviorKey);
Assert.DoesNotContain(regionBehaviorFactory, x => x == RegionBehaviorBMock.BehaviorKey);
Assert.IsType<RegionBehaviorBMock>(regionBehaviorFactory.CreateFromKey(RegionBehaviorAMock.BehaviorKey));
}

[Fact]
public void MissingBehavior_IsAdded()
{
var mauiApp = CreateBuilder(prism => prism
.ConfigureRegionBehaviors(behaviors =>
{
behaviors.AddOrReplace<RegionBehaviorAMock>(RegionBehaviorAMock.BehaviorKey);
}))
.Build();

var regionBehaviorFactory = mauiApp.Services.GetRequiredService<IRegionBehaviorFactory>();

Assert.NotEmpty(regionBehaviorFactory);
Assert.Contains(regionBehaviorFactory, x => x == RegionBehaviorAMock.BehaviorKey);
Assert.IsType<RegionBehaviorAMock>(regionBehaviorFactory.CreateFromKey(RegionBehaviorAMock.BehaviorKey));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
namespace Prism.DryIoc.Maui.Tests.Mocks.Regions.Behaviors;
internal class RegionBehaviorAMock : RegionBehavior
{
public const string BehaviorKey = "RegionBehaviorAMock";
public RegionBehaviorAMock()
{

}
protected override void OnAttach()
{
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
namespace Prism.DryIoc.Maui.Tests.Mocks.Regions.Behaviors;
internal class RegionBehaviorBMock : RegionBehavior
{
public const string BehaviorKey = "RegionBehaviorBMock";
public RegionBehaviorBMock()
{

}
protected override void OnAttach()
{
}
}
21 changes: 21 additions & 0 deletions tests/Wpf/Prism.Wpf.Tests/Mocks/MockRegionBehaviorB.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using Prism.Navigation.Regions;

namespace Prism.Wpf.Tests.Mocks
{
public class MockRegionBehaviorB : IRegionBehavior
{
public IRegion Region
{
get; set;
}

public Func<object> OnAttach;

public void Attach()
{
if (OnAttach != null)
OnAttach();

}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -75,5 +75,38 @@ public void CreateWithUnknownKeyThrows()

}

[Fact]
public void ExistingBehavior_IsReplaced_WithCustomBehavior()
{
var expectedBehavior = new MockRegionBehaviorB();
var containerMock = new Mock<IContainerExtension>();
containerMock.Setup(c => c.Resolve(typeof(MockRegionBehaviorB))).Returns(expectedBehavior);

RegionBehaviorFactory factory = new RegionBehaviorFactory(containerMock.Object);

factory.AddIfMissing<MockRegionBehavior>("key1");
factory.AddOrReplace<MockRegionBehaviorB>("key1");

Assert.Single(factory);
Assert.True(factory.ContainsKey("key1"));
Assert.IsType<MockRegionBehaviorB>(factory.CreateFromKey("key1"));
}

[Fact]
public void MissingBehavior_IsAdded()
{
var expectedBehavior = new MockRegionBehaviorB();
var containerMock = new Mock<IContainerExtension>();
containerMock.Setup(c => c.Resolve(typeof(MockRegionBehaviorB))).Returns(expectedBehavior);

RegionBehaviorFactory factory = new RegionBehaviorFactory(containerMock.Object);

factory.AddOrReplace<MockRegionBehaviorB>("key1");

Assert.Single(factory);
Assert.True(factory.ContainsKey("key1"));
Assert.IsType<MockRegionBehaviorB>(factory.CreateFromKey("key1"));
}

}
}
Loading