Skip to content

Commit

Permalink
Merge pull request #2960 from PrismLibrary/dev/ds/registeronce
Browse files Browse the repository at this point in the history
  • Loading branch information
dansiegel authored Sep 17, 2023
2 parents 91beae0 + 7b438c9 commit 31e4bb3
Show file tree
Hide file tree
Showing 6 changed files with 211 additions and 43 deletions.
24 changes: 12 additions & 12 deletions src/Forms/Prism.Forms/PrismApplicationBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -168,18 +168,18 @@ protected virtual void Initialize()
/// <param name="containerRegistry"></param>
protected virtual void RegisterRequiredTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterSingleton<IApplicationProvider, ApplicationProvider>();
containerRegistry.RegisterSingleton<IApplicationStore, ApplicationStore>();
containerRegistry.RegisterSingleton<IEventAggregator, EventAggregator>();
containerRegistry.RegisterSingleton<IKeyboardMapper, KeyboardMapper>();
containerRegistry.RegisterSingleton<IPageDialogService, PageDialogService>();
containerRegistry.RegisterSingleton<IDialogService, DialogService>();
containerRegistry.RegisterSingleton<IDeviceService, DeviceService>();
containerRegistry.RegisterSingleton<IPageBehaviorFactory, PageBehaviorFactory>();
containerRegistry.RegisterSingleton<IModuleCatalog, ModuleCatalog>();
containerRegistry.RegisterSingleton<IModuleManager, ModuleManager>();
containerRegistry.RegisterSingleton<IModuleInitializer, ModuleInitializer>();
containerRegistry.RegisterScoped<INavigationService, PageNavigationService>();
containerRegistry.TryRegisterSingleton<IApplicationProvider, ApplicationProvider>();
containerRegistry.TryRegisterSingleton<IApplicationStore, ApplicationStore>();
containerRegistry.TryRegisterSingleton<IEventAggregator, EventAggregator>();
containerRegistry.TryRegisterSingleton<IKeyboardMapper, KeyboardMapper>();
containerRegistry.TryRegisterSingleton<IPageDialogService, PageDialogService>();
containerRegistry.TryRegisterSingleton<IDialogService, DialogService>();
containerRegistry.TryRegisterSingleton<IDeviceService, DeviceService>();
containerRegistry.TryRegisterSingleton<IPageBehaviorFactory, PageBehaviorFactory>();
containerRegistry.TryRegisterSingleton<IModuleCatalog, ModuleCatalog>();
containerRegistry.TryRegisterSingleton<IModuleManager, ModuleManager>();
containerRegistry.TryRegisterSingleton<IModuleInitializer, ModuleInitializer>();
containerRegistry.TryRegisterScoped<INavigationService, PageNavigationService>();
containerRegistry.Register<INavigationService, PageNavigationService>(NavigationServiceName);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ private static IServiceCollection RegisterForNavigationWithViewModel(this IServi

internal static IContainerRegistry RegisterRegionServices(this IContainerRegistry containerRegistry, Action<RegionAdapterMappings> configureAdapters = null, Action<IRegionBehaviorFactory> configureBehaviors = null)
{
containerRegistry.Register<IRegionNavigationRegistry, RegionNavigationRegistry>();
containerRegistry.TryRegister<IRegionNavigationRegistry, RegionNavigationRegistry>();
containerRegistry.RegisterSingleton<RegionAdapterMappings>(p =>
{
var regionAdapterMappings = new RegionAdapterMappings();
Expand All @@ -114,10 +114,10 @@ internal static IContainerRegistry RegisterRegionServices(this IContainerRegistr
return regionAdapterMappings;
});

containerRegistry.RegisterSingleton<IRegionManager, RegionManager>();
containerRegistry.RegisterSingleton<IRegionNavigationContentLoader, RegionNavigationContentLoader>();
containerRegistry.RegisterSingleton<IRegionViewRegistry, RegionViewRegistry>();
containerRegistry.Register<RegionBehaviorFactory>();
containerRegistry.TryRegisterSingleton<IRegionManager, RegionManager>();
containerRegistry.TryRegisterSingleton<IRegionNavigationContentLoader, RegionNavigationContentLoader>();
containerRegistry.TryRegisterSingleton<IRegionViewRegistry, RegionViewRegistry>();
containerRegistry.TryRegister<RegionBehaviorFactory>();
containerRegistry.RegisterSingleton<IRegionBehaviorFactory>(p =>
{
var regionBehaviors = p.Resolve<RegionBehaviorFactory>();
Expand All @@ -132,10 +132,10 @@ internal static IContainerRegistry RegisterRegionServices(this IContainerRegistr
configureBehaviors?.Invoke(regionBehaviors);
return regionBehaviors;
});
containerRegistry.Register<IRegionNavigationJournalEntry, RegionNavigationJournalEntry>();
containerRegistry.Register<IRegionNavigationJournal, RegionNavigationJournal>();
containerRegistry.Register<IRegionNavigationService, RegionNavigationService>();
containerRegistry.TryRegister<IRegionNavigationJournalEntry, RegionNavigationJournalEntry>();
containerRegistry.TryRegister<IRegionNavigationJournal, RegionNavigationJournal>();
containerRegistry.TryRegister<IRegionNavigationService, RegionNavigationService>();
//containerRegistry.RegisterManySingleton<RegionResolverOverrides>(typeof(IResolverOverridesHelper), typeof(IActiveRegionHelper));
return containerRegistry.RegisterSingleton<IRegionManager, RegionManager>();
return containerRegistry.TryRegisterSingleton<IRegionManager, RegionManager>();
}
}
16 changes: 8 additions & 8 deletions src/Maui/Prism.Maui/PrismAppBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -220,16 +220,16 @@ public PrismAppBuilder ConfigureRegionBehaviors(Action<IRegionBehaviorFactory> c

private void RegisterDefaultRequiredTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterSingleton<IEventAggregator, EventAggregator>();
containerRegistry.RegisterSingleton<IKeyboardMapper, KeyboardMapper>();
containerRegistry.RegisterScoped<IPageDialogService, PageDialogService>();
containerRegistry.RegisterScoped<IDialogService, DialogService>();
containerRegistry.Register<IDialogViewRegistry, DialogViewRegistry>();
containerRegistry.TryRegisterSingleton<IEventAggregator, EventAggregator>();
containerRegistry.TryRegisterSingleton<IKeyboardMapper, KeyboardMapper>();
containerRegistry.TryRegisterScoped<IPageDialogService, PageDialogService>();
containerRegistry.TryRegisterScoped<IDialogService, DialogService>();
containerRegistry.TryRegister<IDialogViewRegistry, DialogViewRegistry>();
containerRegistry.RegisterDialogContainer<DialogContainerPage>();
//containerRegistry.RegisterSingleton<IDeviceService, DeviceService>();
containerRegistry.RegisterScoped<IPageAccessor, PageAccessor>();
containerRegistry.RegisterScoped<INavigationService, PageNavigationService>();
containerRegistry.Register<INavigationRegistry, NavigationRegistry>();
containerRegistry.TryRegisterScoped<IPageAccessor, PageAccessor>();
containerRegistry.TryRegisterScoped<INavigationService, PageNavigationService>();
containerRegistry.TryRegister<INavigationRegistry, NavigationRegistry>();
containerRegistry.RegisterManySingleton<PrismWindowManager>();
containerRegistry.RegisterPageBehavior<NavigationPage, NavigationPageSystemGoBackBehavior>();
containerRegistry.RegisterPageBehavior<NavigationPage, NavigationPageActiveAwareBehavior>();
Expand Down
135 changes: 135 additions & 0 deletions src/Prism.Core/Ioc/IContainerRegistryExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,141 @@ namespace Prism.Ioc
/// </summary>
public static class IContainerRegistryExtensions
{
/// <summary>
/// Will try to register the service if it has not already been registered
/// </summary>
/// <param name="from">The service type.</param>
/// <param name="to">The implementation type.</param>
/// <param name="containerRegistry">The <see cref="IContainerRegistry"/>.</param>
/// <returns>The <see cref="IContainerRegistry"/>.</returns>
public static IContainerRegistry TryRegister(this IContainerRegistry containerRegistry, Type from, Type to)
{
if (!containerRegistry.IsRegistered(from))
containerRegistry.Register(from, to);

return containerRegistry;
}

/// <summary>
/// Will try to register the service if it has not already been registered
/// </summary>
/// <typeparam name="TFrom">The service type.</typeparam>
/// <typeparam name="TTo">The implementation type.</typeparam>
/// <param name="containerRegistry">The <see cref="IContainerRegistry"/>.</param>
/// <returns>The <see cref="IContainerRegistry"/>.</returns>
public static IContainerRegistry TryRegister<TFrom, TTo>(this IContainerRegistry containerRegistry)
where TTo : TFrom
{
return containerRegistry.TryRegister(typeof(TFrom), typeof(TTo));
}

/// <summary>
/// Will try to register the service if it has not already been registered
/// </summary>
/// <typeparam name="T">The service type.</typeparam>
/// <param name="containerRegistry">The <see cref="IContainerRegistry"/>.</param>
/// <returns>The <see cref="IContainerRegistry"/>.</returns>
public static IContainerRegistry TryRegister<T>(this IContainerRegistry containerRegistry)
where T : class
{
return containerRegistry.TryRegister(typeof(T), typeof(T));
}

/// <summary>
/// Will try to register the service if it has not already been registered
/// </summary>
/// <param name="from">The service type.</param>
/// <param name="to">The implementation type.</param>
/// <param name="containerRegistry">The <see cref="IContainerRegistry"/>.</param>
/// <returns>The <see cref="IContainerRegistry"/>.</returns>
public static IContainerRegistry TryRegisterScoped(this IContainerRegistry containerRegistry, Type from, Type to)
{
if (!containerRegistry.IsRegistered(from))
containerRegistry.RegisterScoped(from, to);

return containerRegistry;
}

/// <summary>
/// Will try to register the service if it has not already been registered
/// </summary>
/// <typeparam name="T">The service type.</typeparam>
/// <param name="containerRegistry">The <see cref="IContainerRegistry"/>.</param>
/// <returns>The <see cref="IContainerRegistry"/>.</returns>
public static IContainerRegistry TryRegisterScoped<T>(this IContainerRegistry containerRegistry)
where T : class
{
return containerRegistry.TryRegisterScoped(typeof(T), typeof(T));
}

/// <summary>
/// Will try to register the service if it has not already been registered
/// </summary>
/// <typeparam name="TFrom">The service type.</typeparam>
/// <typeparam name="TTo">The implementation type.</typeparam>
/// <param name="containerRegistry">The <see cref="IContainerRegistry"/>.</param>
/// <returns>The <see cref="IContainerRegistry"/>.</returns>
public static IContainerRegistry TryRegisterScoped<TFrom, TTo>(this IContainerRegistry containerRegistry)
where TTo : TFrom
{
return containerRegistry.TryRegisterScoped(typeof(TFrom), typeof(TTo));
}

/// <summary>
/// Will try to register the service if it has not already been registered
/// </summary>
/// <param name="from">The service type.</param>
/// <param name="to">The implementation type.</param>
/// <param name="containerRegistry">The <see cref="IContainerRegistry"/>.</param>
/// <returns>The <see cref="IContainerRegistry"/>.</returns>
public static IContainerRegistry TryRegisterSingleton(this IContainerRegistry containerRegistry, Type from, Type to)
{
if (!containerRegistry.IsRegistered(from))
containerRegistry.RegisterSingleton(from, to);

return containerRegistry;
}

/// <summary>
/// Will try to register the service if it has not already been registered
/// </summary>
/// <typeparam name="TFrom">The service type.</typeparam>
/// <typeparam name="TTo">The implementation type.</typeparam>
/// <param name="containerRegistry">The <see cref="IContainerRegistry"/>.</param>
/// <returns>The <see cref="IContainerRegistry"/>.</returns>
public static IContainerRegistry TryRegisterSingleton<TFrom, TTo>(this IContainerRegistry containerRegistry)
where TTo : TFrom
{
return containerRegistry.TryRegisterSingleton(typeof(TFrom), typeof(TTo));
}

/// <summary>
/// Will try to register the service if it has not already been registered
/// </summary>
/// <typeparam name="T">The service type.</typeparam>
/// <param name="containerRegistry">The <see cref="IContainerRegistry"/>.</param>
/// <returns>The <see cref="IContainerRegistry"/>.</returns>
public static IContainerRegistry TryRegisterSingleton<T>(this IContainerRegistry containerRegistry)
where T : class
{
return containerRegistry.TryRegisterSingleton(typeof(T), typeof(T));
}

/// <summary>
/// Will try to register the service if it has not already been registered
/// </summary>
/// <typeparam name="T">The service type.</typeparam>
/// <param name="containerRegistry">The <see cref="IContainerRegistry"/>.</param>
/// <param name="instance">An instance of the service.</param>
/// <returns>The <see cref="IContainerRegistry"/>.</returns>
public static IContainerRegistry TryRegisterInstance<T>(this IContainerRegistry containerRegistry, T instance)
{
if (!containerRegistry.IsRegistered<T>())
containerRegistry.RegisterInstance(instance);

return containerRegistry;
}

/// <summary>
/// Registers an instance of a given <see cref="Type"/>
/// </summary>
Expand Down
28 changes: 14 additions & 14 deletions src/Wpf/Prism.Wpf/PrismInitializationExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,20 +28,20 @@ internal static void ConfigureViewModelLocator()

internal static void RegisterRequiredTypes(this IContainerRegistry containerRegistry, IModuleCatalog moduleCatalog)
{
containerRegistry.RegisterInstance(moduleCatalog);
containerRegistry.RegisterSingleton<IDialogService, DialogService>();
containerRegistry.RegisterSingleton<IModuleInitializer, ModuleInitializer>();
containerRegistry.RegisterSingleton<IModuleManager, ModuleManager>();
containerRegistry.RegisterSingleton<RegionAdapterMappings>();
containerRegistry.RegisterSingleton<IRegionManager, RegionManager>();
containerRegistry.RegisterSingleton<IRegionNavigationContentLoader, RegionNavigationContentLoader>();
containerRegistry.RegisterSingleton<IEventAggregator, EventAggregator>();
containerRegistry.RegisterSingleton<IRegionViewRegistry, RegionViewRegistry>();
containerRegistry.RegisterSingleton<IRegionBehaviorFactory, RegionBehaviorFactory>();
containerRegistry.Register<IRegionNavigationJournalEntry, RegionNavigationJournalEntry>();
containerRegistry.Register<IRegionNavigationJournal, RegionNavigationJournal>();
containerRegistry.Register<IRegionNavigationService, RegionNavigationService>();
containerRegistry.Register<IDialogWindow, DialogWindow>(); //default dialog host
containerRegistry.TryRegisterInstance(moduleCatalog);
containerRegistry.TryRegisterSingleton<IDialogService, DialogService>();
containerRegistry.TryRegisterSingleton<IModuleInitializer, ModuleInitializer>();
containerRegistry.TryRegisterSingleton<IModuleManager, ModuleManager>();
containerRegistry.TryRegisterSingleton<RegionAdapterMappings>();
containerRegistry.TryRegisterSingleton<IRegionManager, RegionManager>();
containerRegistry.TryRegisterSingleton<IRegionNavigationContentLoader, RegionNavigationContentLoader>();
containerRegistry.TryRegisterSingleton<IEventAggregator, EventAggregator>();
containerRegistry.TryRegisterSingleton<IRegionViewRegistry, RegionViewRegistry>();
containerRegistry.TryRegisterSingleton<IRegionBehaviorFactory, RegionBehaviorFactory>();
containerRegistry.TryRegister<IRegionNavigationJournalEntry, RegionNavigationJournalEntry>();
containerRegistry.TryRegister<IRegionNavigationJournal, RegionNavigationJournal>();
containerRegistry.TryRegister<IRegionNavigationService, RegionNavigationService>();
containerRegistry.TryRegister<IDialogWindow, DialogWindow>(); //default dialog host
}

internal static void RegisterDefaultRegionBehaviors(this IRegionBehaviorFactory regionBehaviors)
Expand Down
33 changes: 33 additions & 0 deletions tests/Containers/Prism.Container.Shared/Tests/ContainerFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -741,5 +741,38 @@ public void RegisterInstance_RegistersIEnumerable()
}

#endif

[Fact]
public void TryRegisterTransientDoesNotReplaceOriginalRegistration()
{
Setup.CreateContainer();
Setup.Registry.TryRegister<IServiceA, ServiceA>();
Setup.Registry.TryRegister<IServiceA, CompositeService>();

var service = Setup.Container.Resolve<IServiceA>();
Assert.IsType<ServiceA>(service);
}

[Fact]
public void TryRegisterScopedDoesNotReplaceOriginalRegistration()
{
Setup.CreateContainer();
Setup.Registry.TryRegisterScoped<IServiceA, ServiceA>();
Setup.Registry.TryRegisterScoped<IServiceA, CompositeService>();

var service = Setup.Container.Resolve<IServiceA>();
Assert.IsType<ServiceA>(service);
}

[Fact]
public void TryRegisterSingletonDoesNotReplaceOriginalRegistration()
{
Setup.CreateContainer();
Setup.Registry.TryRegisterSingleton<IServiceA, ServiceA>();
Setup.Registry.TryRegisterSingleton<IServiceA, CompositeService>();

var service = Setup.Container.Resolve<IServiceA>();
Assert.IsType<ServiceA>(service);
}
}
}

0 comments on commit 31e4bb3

Please sign in to comment.