Skip to content

Commit

Permalink
ensure we resolve concrete types
Browse files Browse the repository at this point in the history
  • Loading branch information
dansiegel committed Jun 29, 2020
1 parent 92be064 commit 4c4ea40
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Linq;
using System.Runtime.CompilerServices;
using Microsoft.Extensions.DependencyInjection;
using Prism.Ioc;
Expand All @@ -19,5 +20,28 @@ public static IServiceCollection ServiceCollection(this IContainerRegistry conta

throw new NotImplementedException("IContainerRegistry must be implmented from the concrete type PrismContainerExtension");
}

internal static object GetOrConstructService(this IServiceProvider provider, Type type, params (Type Type, object Instance)[] parameters)
{
var instance = provider.GetService(type);
if (instance is null && !type.IsInterface && !type.IsAbstract)
{
var ctor = type.GetConstructors().OrderByDescending(x => x.GetParameters().Length).FirstOrDefault();
if (ctor is null)
throw new NullReferenceException($"Could not locate a public constructor for {type.FullName}");

var ctorParameters = ctor.GetParameters();
var args = ctor.GetParameters().Select(x =>
{
object arg = parameters.FirstOrDefault(p => x.ParameterType.IsAssignableFrom(p.Instance.GetType())).Instance;
if (arg != null)
return arg;

return provider.GetService(x.ParameterType);
});
return ctor.Invoke(args.ToArray());
}
return instance;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@ public object GetService(IServiceProvider serviceProvider, string name, Type typ
return registry?.GetService(serviceProvider);
}

public Type GetRegistrationType(string key)
{
return Services.FirstOrDefault(x => x.Name.Equals(key, StringComparison.OrdinalIgnoreCase) || x.ImplementationType.Name.Equals(key, StringComparison.OrdinalIgnoreCase))?.ImplementationType;
}

private void CheckDuplicate(string name, Type serviceType)
{
var registry = GetServiceRegistry(name, serviceType);
Expand All @@ -73,7 +78,7 @@ class NamedService
public Type ImplementationType { get; set; }

public virtual object GetService(IServiceProvider serviceProvider) =>
serviceProvider.GetService(ImplementationType);
serviceProvider.GetOrConstructService(ImplementationType);
}

class NamedSingletonService : NamedService
Expand All @@ -84,7 +89,7 @@ public override object GetService(IServiceProvider serviceProvider)
{
if(Instance is null)
{
Instance = serviceProvider.GetService(ImplementationType);
Instance = serviceProvider.GetOrConstructService(ImplementationType);
}

return Instance;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,16 @@ public object Resolve(Type type, string name) =>

public object Resolve(Type type, params (Type Type, object Instance)[] parameters)
{
var provider = parameters.Length > 0 ? GetChildProvider(parameters) : Instance;
return provider.GetService(type) ?? throw NullResolutionException(type);
try
{
var provider = parameters.Length > 0 ? GetChildProvider(parameters) : Instance;

return provider.GetOrConstructService(type, parameters) ?? throw NullResolutionException(type);
}
catch (Exception ex)
{
throw new ContainerResolutionException(type, ex);
}
}

public object Resolve(Type type, string name, params (Type Type, object Instance)[] parameters)
Expand Down

0 comments on commit 4c4ea40

Please sign in to comment.