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

Adding IContainerInfo #2060

Merged
merged 2 commits into from
Apr 16, 2020
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
12 changes: 11 additions & 1 deletion src/Containers/Prism.DryIoc.Shared/DryIocContainerExtension.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@
using System.Linq;
using DryIoc;
using Prism.Ioc;
using Prism.Ioc.Internals;

namespace Prism.DryIoc
{
/// <summary>
/// The <see cref="IContainerExtension" /> Implementation to use with DryIoc
/// </summary>
public class DryIocContainerExtension : IContainerExtension<IContainer>
public class DryIocContainerExtension : IContainerExtension<IContainer>, IContainerInfo
{
/// <summary>
/// The instance of the wrapped container
Expand Down Expand Up @@ -173,5 +174,14 @@ public bool IsRegistered(Type type, string name)
{
return Instance.IsRegistered(type, name);
}

Type IContainerInfo.GetRegistrationType(string key)
{
var matchingRegistration = Instance.GetServiceRegistrations().Where(r => key.Equals(r.OptionalServiceKey?.ToString(), StringComparison.Ordinal)).FirstOrDefault();
if (matchingRegistration.OptionalServiceKey == null)
matchingRegistration = Instance.GetServiceRegistrations().Where(r => key.Equals(r.ImplementationType.Name, StringComparison.Ordinal)).FirstOrDefault();

return matchingRegistration.ImplementationType;
}
}
}
15 changes: 14 additions & 1 deletion src/Containers/Prism.Unity.Shared/UnityContainerExtension.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Linq;
using Prism.Ioc;
using Prism.Ioc.Internals;
using Unity;
using Unity.Resolution;

Expand All @@ -9,7 +10,7 @@ namespace Prism.Unity
/// <summary>
/// The Unity implementation of the <see cref="IContainerExtension" />
/// </summary>
public class UnityContainerExtension : IContainerExtension<IUnityContainer>
public class UnityContainerExtension : IContainerExtension<IUnityContainer>, IContainerInfo
{
/// <summary>
/// The instance of the wrapped container
Expand Down Expand Up @@ -183,5 +184,17 @@ public bool IsRegistered(Type type, string name)
{
return Instance.IsRegistered(type, name);
}

Type IContainerInfo.GetRegistrationType(string key)
{
//First try friendly name registration. If not found, try type registration
var matchingRegistration = Instance.Registrations.Where(r => key.Equals(r.Name, StringComparison.Ordinal)).FirstOrDefault();
if (matchingRegistration == null)
{
matchingRegistration = Instance.Registrations.Where(r => key.Equals(r.RegisteredType.Name, StringComparison.Ordinal)).FirstOrDefault();
}

return matchingRegistration?.MappedToType;
}
}
}
20 changes: 20 additions & 0 deletions src/Prism.Core/Ioc/Internals/IContainerInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using System;
using System.ComponentModel;

namespace Prism.Ioc.Internals
{
/// <summary>
/// Used to resolve the registered implementation type for a given key
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
public interface IContainerInfo
{
/// <summary>
/// Locates the registered implementation <see cref="Type"/> for a give key
/// </summary>
/// <param name="key">Registration Key</param>
/// <returns>Implementation <see cref="Type"/></returns>
[EditorBrowsable(EditorBrowsableState.Never)]
Type GetRegistrationType(string key);
}
}
27 changes: 27 additions & 0 deletions src/Prism.Core/Ioc/Internals/IContainerInfoExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using System;
using System.ComponentModel;

namespace Prism.Ioc.Internals
{
/// <summary>
/// Internal extensions to get the registered implementation for Regions
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
public static class IContainerInfoExtensions
{
/// <summary>
/// Locates the registered implementation <see cref="Type"/> for a give key
/// </summary>
/// <param name="container">The <see cref="IContainerExtension"/></param>
/// <param name="key">Registration Key</param>
/// <returns>Implementation <see cref="Type"/></returns>
[EditorBrowsable(EditorBrowsableState.Never)]
public static Type GetRegistrationType(this IContainerExtension container, string key)
{
if (container is IContainerInfo ci)
return ci.GetRegistrationType(key);

return null;
}
}
}
5 changes: 2 additions & 3 deletions src/Wpf/Prism.DryIoc.Wpf/Legacy/DryIocBootstrapper.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
using System;
using System;
using System.Globalization;
using DryIoc;
using Prism.DryIoc.Properties;
using Prism.DryIoc.Regions;
using Prism.Events;
using Prism.Ioc;
using Prism.Logging;
Expand Down Expand Up @@ -147,7 +146,7 @@ protected virtual void ConfigureContainer()
RegisterTypeIfMissing<IRegionNavigationJournalEntry, RegionNavigationJournalEntry>(false);
RegisterTypeIfMissing<IRegionNavigationJournal, RegionNavigationJournal>(false);
RegisterTypeIfMissing<IRegionNavigationService, RegionNavigationService>(false);
RegisterTypeIfMissing<IRegionNavigationContentLoader, DryIocRegionNavigationContentLoader>(true);
RegisterTypeIfMissing<IRegionNavigationContentLoader, RegionNavigationContentLoader>(true);
}
}

Expand Down
7 changes: 0 additions & 7 deletions src/Wpf/Prism.DryIoc.Wpf/PrismApplication.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using System;
using DryIoc;
using Prism.DryIoc.Regions;
using Prism.Ioc;
using Prism.Regions;

Expand All @@ -21,12 +20,6 @@ protected override IContainerExtension CreateContainerExtension()
return new DryIocContainerExtension(new Container(CreateContainerRules()));
}

protected override void RegisterRequiredTypes(IContainerRegistry containerRegistry)
{
base.RegisterRequiredTypes(containerRegistry);
containerRegistry.RegisterSingleton<IRegionNavigationContentLoader, DryIocRegionNavigationContentLoader>();
}

protected override void RegisterFrameworkExceptionTypes()
{
ExceptionExtensions.RegisterFrameworkExceptionType(typeof(ContainerException));
Expand Down

This file was deleted.

3 changes: 1 addition & 2 deletions src/Wpf/Prism.Unity.Wpf/Legacy/UnityBootstrapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
using Prism.Regions;
using Prism.Services.Dialogs;
using Prism.Unity.Properties;
using Prism.Unity.Regions;
using Unity;
using Unity.Lifetime;

Expand Down Expand Up @@ -143,7 +142,7 @@ protected virtual void ConfigureContainer()
RegisterTypeIfMissing(typeof(IRegionNavigationJournalEntry), typeof(RegionNavigationJournalEntry), false);
RegisterTypeIfMissing(typeof(IRegionNavigationJournal), typeof(RegionNavigationJournal), false);
RegisterTypeIfMissing(typeof(IRegionNavigationService), typeof(RegionNavigationService), false);
RegisterTypeIfMissing(typeof(IRegionNavigationContentLoader), typeof(UnityRegionNavigationContentLoader), true);
RegisterTypeIfMissing(typeof(IRegionNavigationContentLoader), typeof(RegionNavigationContentLoader), true);
}
}

Expand Down
8 changes: 0 additions & 8 deletions src/Wpf/Prism.Unity.Wpf/PrismApplication.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
using System;
using Prism.Ioc;
using Prism.Regions;
using Prism.Unity.Regions;
using Unity;

namespace Prism.Unity
Expand All @@ -13,12 +11,6 @@ protected override IContainerExtension CreateContainerExtension()
return new UnityContainerExtension();
}

protected override void RegisterRequiredTypes(IContainerRegistry containerRegistry)
{
base.RegisterRequiredTypes(containerRegistry);
containerRegistry.RegisterSingleton<IRegionNavigationContentLoader, UnityRegionNavigationContentLoader>();
}

protected override void RegisterFrameworkExceptionTypes()
{
ExceptionExtensions.RegisterFrameworkExceptionType(typeof(ResolutionFailedException));
Expand Down

This file was deleted.

40 changes: 35 additions & 5 deletions src/Wpf/Prism.Wpf/Regions/RegionNavigationContentLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Windows;
using Prism.Common;
using Prism.Ioc;
using Prism.Ioc.Internals;
using Prism.Properties;

namespace Prism.Regions
Expand All @@ -15,7 +16,7 @@ namespace Prism.Regions
/// </summary>
public class RegionNavigationContentLoader : IRegionNavigationContentLoader
{
private readonly IContainerProvider _container;
private readonly IContainerExtension _container;

/// <summary>
/// Initializes a new instance of the <see cref="RegionNavigationContentLoader"/> class with a service locator.
Expand Down Expand Up @@ -127,12 +128,41 @@ protected virtual string GetContractFromNavigationContext(NavigationContext navi
/// <returns>An enumerable of candidate objects from the <see cref="IRegion"/></returns>
protected virtual IEnumerable<object> GetCandidatesFromRegion(IRegion region, string candidateNavigationContract)
{
if (region == null)
if (region is null)
{
throw new ArgumentNullException(nameof(region));
}

if (string.IsNullOrEmpty(candidateNavigationContract))
{
throw new ArgumentNullException(nameof(candidateNavigationContract));
}

var contractCandidates = GetCandidatesFromRegionViews(region, candidateNavigationContract);

if (!contractCandidates.Any())
{
var matchingType = _container.GetRegistrationType(candidateNavigationContract);
if (matchingType is null)
{
return Array.Empty<object>();
}

return region.Views.Where(v =>
string.Equals(v.GetType().Name, candidateNavigationContract, StringComparison.Ordinal) ||
string.Equals(v.GetType().FullName, candidateNavigationContract, StringComparison.Ordinal));
return GetCandidatesFromRegionViews(region, matchingType.FullName);
}

return contractCandidates;
}

private IEnumerable<object> GetCandidatesFromRegionViews(IRegion region, string candidateNavigationContract)
{
return region.Views.Where(v => ViewIsMatch(v.GetType(), candidateNavigationContract));
}

private static bool ViewIsMatch(Type viewType, string navigationSegment)
{
var names = new[] { viewType.Name, viewType.FullName };
return names.Any(x => x.Equals(navigationSegment, StringComparison.Ordinal));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public RegionNavigationContentLoaderFixture()
_container = CreateContainerExtension();
_container.RegisterInstance<IContainerExtension>(_container);
_container.Register<IRegionNavigationService, RegionNavigationService>();
_container.Register(typeof(IRegionNavigationContentLoader), RegionNavigationContentLoaderType);
_container.Register(typeof(IRegionNavigationContentLoader), typeof(RegionNavigationContentLoader));
_container.Register<IRegionNavigationJournal, RegionNavigationJournal>();
ContainerLocator.ResetContainer();
ContainerLocator.SetContainerExtension(() => _container);
Expand Down
3 changes: 0 additions & 3 deletions tests/Wpf/Prism.DryIoc.Wpf.Tests/ContainerHelper.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using System;
using DryIoc;
using Prism.DryIoc;
using Prism.DryIoc.Regions;
using Prism.Ioc;

namespace Prism.Container.Wpf.Tests
Expand Down Expand Up @@ -31,7 +30,5 @@ public static IContainer GetBaseContainer(this IContainerProvider container) =>
public static Type BaseContainerInterfaceType = typeof(IContainer);

public static Type RegisteredFrameworkException = typeof(ContainerException);

public static Type RegionNavigationContentLoaderType = typeof(DryIocRegionNavigationContentLoader);
}
}
3 changes: 0 additions & 3 deletions tests/Wpf/Prism.Unity.Wpf.Tests/ContainerHelper.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using System;
using Prism.Ioc;
using Prism.Unity;
using Prism.Unity.Regions;
using Unity;

namespace Prism.Container.Wpf.Tests
Expand All @@ -27,7 +26,5 @@ public static IUnityContainer GetBaseContainer(this IContainerProvider container
public static Type BaseContainerInterfaceType = typeof(IUnityContainer);

public static Type RegisteredFrameworkException = typeof(ResolutionFailedException);

public static Type RegionNavigationContentLoaderType = typeof(UnityRegionNavigationContentLoader);
}
}