From 26eebed93e926a795132340cc8db0ef03acb9647 Mon Sep 17 00:00:00 2001 From: Dan Siegel Date: Sat, 16 Sep 2023 16:15:56 -0600 Subject: [PATCH 1/2] feat: adding TryRegister --- .../Ioc/IContainerRegistryExtensions.cs | 135 ++++++++++++++++++ .../Tests/ContainerFixture.cs | 33 +++++ 2 files changed, 168 insertions(+) diff --git a/src/Prism.Core/Ioc/IContainerRegistryExtensions.cs b/src/Prism.Core/Ioc/IContainerRegistryExtensions.cs index 7c2d81f8e1..18c57c5945 100644 --- a/src/Prism.Core/Ioc/IContainerRegistryExtensions.cs +++ b/src/Prism.Core/Ioc/IContainerRegistryExtensions.cs @@ -7,6 +7,141 @@ namespace Prism.Ioc /// public static class IContainerRegistryExtensions { + /// + /// Will try to register the service if it has not already been registered + /// + /// The service type. + /// The implementation type. + /// The . + /// The . + public static IContainerRegistry TryRegister(this IContainerRegistry containerRegistry, Type from, Type to) + { + if (!containerRegistry.IsRegistered(from)) + containerRegistry.Register(from, to); + + return containerRegistry; + } + + /// + /// Will try to register the service if it has not already been registered + /// + /// The service type. + /// The implementation type. + /// The . + /// The . + public static IContainerRegistry TryRegister(this IContainerRegistry containerRegistry) + where TTo : TFrom + { + return containerRegistry.TryRegister(typeof(TFrom), typeof(TTo)); + } + + /// + /// Will try to register the service if it has not already been registered + /// + /// The service type. + /// The . + /// The . + public static IContainerRegistry TryRegister(this IContainerRegistry containerRegistry) + where T : class + { + return containerRegistry.TryRegister(typeof(T), typeof(T)); + } + + /// + /// Will try to register the service if it has not already been registered + /// + /// The service type. + /// The implementation type. + /// The . + /// The . + public static IContainerRegistry TryRegisterScoped(this IContainerRegistry containerRegistry, Type from, Type to) + { + if (!containerRegistry.IsRegistered(from)) + containerRegistry.RegisterScoped(from, to); + + return containerRegistry; + } + + /// + /// Will try to register the service if it has not already been registered + /// + /// The service type. + /// The . + /// The . + public static IContainerRegistry TryRegisterScoped(this IContainerRegistry containerRegistry) + where T : class + { + return containerRegistry.TryRegisterScoped(typeof(T), typeof(T)); + } + + /// + /// Will try to register the service if it has not already been registered + /// + /// The service type. + /// The implementation type. + /// The . + /// The . + public static IContainerRegistry TryRegisterScoped(this IContainerRegistry containerRegistry) + where TTo : TFrom + { + return containerRegistry.TryRegisterScoped(typeof(TFrom), typeof(TTo)); + } + + /// + /// Will try to register the service if it has not already been registered + /// + /// The service type. + /// The implementation type. + /// The . + /// The . + public static IContainerRegistry TryRegisterSingleton(this IContainerRegistry containerRegistry, Type from, Type to) + { + if (!containerRegistry.IsRegistered(from)) + containerRegistry.RegisterSingleton(from, to); + + return containerRegistry; + } + + /// + /// Will try to register the service if it has not already been registered + /// + /// The service type. + /// The implementation type. + /// The . + /// The . + public static IContainerRegistry TryRegisterSingleton(this IContainerRegistry containerRegistry) + where TTo : TFrom + { + return containerRegistry.TryRegisterSingleton(typeof(TFrom), typeof(TTo)); + } + + /// + /// Will try to register the service if it has not already been registered + /// + /// The service type. + /// The . + /// The . + public static IContainerRegistry TryRegisterSingleton(this IContainerRegistry containerRegistry) + where T : class + { + return containerRegistry.TryRegisterSingleton(typeof(T), typeof(T)); + } + + /// + /// Will try to register the service if it has not already been registered + /// + /// The service type. + /// The . + /// An instance of the service. + /// The . + public static IContainerRegistry TryRegisterInstance(this IContainerRegistry containerRegistry, T instance) + { + if (!containerRegistry.IsRegistered()) + containerRegistry.RegisterInstance(instance); + + return containerRegistry; + } + /// /// Registers an instance of a given /// diff --git a/tests/Containers/Prism.Container.Shared/Tests/ContainerFixture.cs b/tests/Containers/Prism.Container.Shared/Tests/ContainerFixture.cs index ab3a089fc9..099c7533f6 100644 --- a/tests/Containers/Prism.Container.Shared/Tests/ContainerFixture.cs +++ b/tests/Containers/Prism.Container.Shared/Tests/ContainerFixture.cs @@ -741,5 +741,38 @@ public void RegisterInstance_RegistersIEnumerable() } #endif + + [Fact] + public void TryRegisterTransientDoesNotReplaceOriginalRegistration() + { + Setup.CreateContainer(); + Setup.Registry.TryRegister(); + Setup.Registry.TryRegister(); + + var service = Setup.Container.Resolve(); + Assert.IsType(service); + } + + [Fact] + public void TryRegisterScopedDoesNotReplaceOriginalRegistration() + { + Setup.CreateContainer(); + Setup.Registry.TryRegisterScoped(); + Setup.Registry.TryRegisterScoped(); + + var service = Setup.Container.Resolve(); + Assert.IsType(service); + } + + [Fact] + public void TryRegisterSingletonDoesNotReplaceOriginalRegistration() + { + Setup.CreateContainer(); + Setup.Registry.TryRegisterSingleton(); + Setup.Registry.TryRegisterSingleton(); + + var service = Setup.Container.Resolve(); + Assert.IsType(service); + } } } From 7b438c9e8486f57445c5c644adb3d85dbb63e989 Mon Sep 17 00:00:00 2001 From: Dan Siegel Date: Sat, 16 Sep 2023 16:29:28 -0600 Subject: [PATCH 2/2] chore: use TryRegister --- src/Forms/Prism.Forms/PrismApplicationBase.cs | 24 ++++++++-------- .../RegionNavigationRegistrationExtensions.cs | 18 ++++++------ src/Maui/Prism.Maui/PrismAppBuilder.cs | 16 +++++------ .../PrismInitializationExtensions.cs | 28 +++++++++---------- 4 files changed, 43 insertions(+), 43 deletions(-) diff --git a/src/Forms/Prism.Forms/PrismApplicationBase.cs b/src/Forms/Prism.Forms/PrismApplicationBase.cs index 07525c6449..3a8d2881af 100644 --- a/src/Forms/Prism.Forms/PrismApplicationBase.cs +++ b/src/Forms/Prism.Forms/PrismApplicationBase.cs @@ -168,18 +168,18 @@ protected virtual void Initialize() /// protected virtual void RegisterRequiredTypes(IContainerRegistry containerRegistry) { - containerRegistry.RegisterSingleton(); - containerRegistry.RegisterSingleton(); - containerRegistry.RegisterSingleton(); - containerRegistry.RegisterSingleton(); - containerRegistry.RegisterSingleton(); - containerRegistry.RegisterSingleton(); - containerRegistry.RegisterSingleton(); - containerRegistry.RegisterSingleton(); - containerRegistry.RegisterSingleton(); - containerRegistry.RegisterSingleton(); - containerRegistry.RegisterSingleton(); - containerRegistry.RegisterScoped(); + containerRegistry.TryRegisterSingleton(); + containerRegistry.TryRegisterSingleton(); + containerRegistry.TryRegisterSingleton(); + containerRegistry.TryRegisterSingleton(); + containerRegistry.TryRegisterSingleton(); + containerRegistry.TryRegisterSingleton(); + containerRegistry.TryRegisterSingleton(); + containerRegistry.TryRegisterSingleton(); + containerRegistry.TryRegisterSingleton(); + containerRegistry.TryRegisterSingleton(); + containerRegistry.TryRegisterSingleton(); + containerRegistry.TryRegisterScoped(); containerRegistry.Register(NavigationServiceName); } diff --git a/src/Maui/Prism.Maui/Ioc/RegionNavigationRegistrationExtensions.cs b/src/Maui/Prism.Maui/Ioc/RegionNavigationRegistrationExtensions.cs index 2edbc23519..3850b841e1 100644 --- a/src/Maui/Prism.Maui/Ioc/RegionNavigationRegistrationExtensions.cs +++ b/src/Maui/Prism.Maui/Ioc/RegionNavigationRegistrationExtensions.cs @@ -98,7 +98,7 @@ private static IServiceCollection RegisterForNavigationWithViewModel(this IServi internal static IContainerRegistry RegisterRegionServices(this IContainerRegistry containerRegistry, Action configureAdapters = null, Action configureBehaviors = null) { - containerRegistry.Register(); + containerRegistry.TryRegister(); containerRegistry.RegisterSingleton(p => { var regionAdapterMappings = new RegionAdapterMappings(); @@ -114,10 +114,10 @@ internal static IContainerRegistry RegisterRegionServices(this IContainerRegistr return regionAdapterMappings; }); - containerRegistry.RegisterSingleton(); - containerRegistry.RegisterSingleton(); - containerRegistry.RegisterSingleton(); - containerRegistry.Register(); + containerRegistry.TryRegisterSingleton(); + containerRegistry.TryRegisterSingleton(); + containerRegistry.TryRegisterSingleton(); + containerRegistry.TryRegister(); containerRegistry.RegisterSingleton(p => { var regionBehaviors = p.Resolve(); @@ -132,10 +132,10 @@ internal static IContainerRegistry RegisterRegionServices(this IContainerRegistr configureBehaviors?.Invoke(regionBehaviors); return regionBehaviors; }); - containerRegistry.Register(); - containerRegistry.Register(); - containerRegistry.Register(); + containerRegistry.TryRegister(); + containerRegistry.TryRegister(); + containerRegistry.TryRegister(); //containerRegistry.RegisterManySingleton(typeof(IResolverOverridesHelper), typeof(IActiveRegionHelper)); - return containerRegistry.RegisterSingleton(); + return containerRegistry.TryRegisterSingleton(); } } diff --git a/src/Maui/Prism.Maui/PrismAppBuilder.cs b/src/Maui/Prism.Maui/PrismAppBuilder.cs index 0f872aca8e..6dcaa4bb5b 100644 --- a/src/Maui/Prism.Maui/PrismAppBuilder.cs +++ b/src/Maui/Prism.Maui/PrismAppBuilder.cs @@ -220,16 +220,16 @@ public PrismAppBuilder ConfigureRegionBehaviors(Action c private void RegisterDefaultRequiredTypes(IContainerRegistry containerRegistry) { - containerRegistry.RegisterSingleton(); - containerRegistry.RegisterSingleton(); - containerRegistry.RegisterScoped(); - containerRegistry.RegisterScoped(); - containerRegistry.Register(); + containerRegistry.TryRegisterSingleton(); + containerRegistry.TryRegisterSingleton(); + containerRegistry.TryRegisterScoped(); + containerRegistry.TryRegisterScoped(); + containerRegistry.TryRegister(); containerRegistry.RegisterDialogContainer(); //containerRegistry.RegisterSingleton(); - containerRegistry.RegisterScoped(); - containerRegistry.RegisterScoped(); - containerRegistry.Register(); + containerRegistry.TryRegisterScoped(); + containerRegistry.TryRegisterScoped(); + containerRegistry.TryRegister(); containerRegistry.RegisterManySingleton(); containerRegistry.RegisterPageBehavior(); containerRegistry.RegisterPageBehavior(); diff --git a/src/Wpf/Prism.Wpf/PrismInitializationExtensions.cs b/src/Wpf/Prism.Wpf/PrismInitializationExtensions.cs index 284ec129e3..b6059795d5 100644 --- a/src/Wpf/Prism.Wpf/PrismInitializationExtensions.cs +++ b/src/Wpf/Prism.Wpf/PrismInitializationExtensions.cs @@ -28,20 +28,20 @@ internal static void ConfigureViewModelLocator() internal static void RegisterRequiredTypes(this IContainerRegistry containerRegistry, IModuleCatalog moduleCatalog) { - containerRegistry.RegisterInstance(moduleCatalog); - containerRegistry.RegisterSingleton(); - containerRegistry.RegisterSingleton(); - containerRegistry.RegisterSingleton(); - containerRegistry.RegisterSingleton(); - containerRegistry.RegisterSingleton(); - containerRegistry.RegisterSingleton(); - containerRegistry.RegisterSingleton(); - containerRegistry.RegisterSingleton(); - containerRegistry.RegisterSingleton(); - containerRegistry.Register(); - containerRegistry.Register(); - containerRegistry.Register(); - containerRegistry.Register(); //default dialog host + containerRegistry.TryRegisterInstance(moduleCatalog); + containerRegistry.TryRegisterSingleton(); + containerRegistry.TryRegisterSingleton(); + containerRegistry.TryRegisterSingleton(); + containerRegistry.TryRegisterSingleton(); + containerRegistry.TryRegisterSingleton(); + containerRegistry.TryRegisterSingleton(); + containerRegistry.TryRegisterSingleton(); + containerRegistry.TryRegisterSingleton(); + containerRegistry.TryRegisterSingleton(); + containerRegistry.TryRegister(); + containerRegistry.TryRegister(); + containerRegistry.TryRegister(); + containerRegistry.TryRegister(); //default dialog host } internal static void RegisterDefaultRegionBehaviors(this IRegionBehaviorFactory regionBehaviors)