Skip to content

Commit

Permalink
v8 updates - fixes for MS Extensions DI
Browse files Browse the repository at this point in the history
  • Loading branch information
dansiegel committed Aug 28, 2020
1 parent dc63d44 commit 3b7915e
Show file tree
Hide file tree
Showing 30 changed files with 368 additions and 90 deletions.
5 changes: 5 additions & 0 deletions Directory.build.props
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,9 @@
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
</PropertyGroup>

<ItemGroup Condition=" $(ProjectName.EndsWith('Tests')) ">
<Content Include="$(MSBuildThisFileDirectory)xunit.runner.json"
CopyToOutputDirectory="always" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="3.1.5" />
<PackageReference Include="Prism.Core" Version="8.0.0.1740-pre" />
<PackageReference Include="Prism.Core" Version="8.0.0.1850-pre" />
</ItemGroup>

</Project>
2 changes: 1 addition & 1 deletion src/Prism.DryIoc.Extensions/Prism.DryIoc.Extensions.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="DryIoc.dll" Version="4.3.2" />
<PackageReference Include="DryIoc.dll" Version="4.3.3" />
</ItemGroup>

<ItemGroup>
Expand Down
12 changes: 6 additions & 6 deletions src/Prism.Forms.Extended/Ioc/RequiredTypesExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public static class RequiredTypesExtensions

public static void RegisterRequiredTypes(this IContainerRegistry containerRegistry)
{
containerRegistry.RegisterManySingletonOnce<AggregateLogger>();
containerRegistry.RegisterManySingletonOnce<AggregateLogger>(typeof(IAggregateLogger), typeof(ILogger), typeof(IAnalyticsService), typeof(ICrashesService));
containerRegistry.RegisterSingletonOnce<IApplicationProvider, ApplicationProvider>();
containerRegistry.RegisterSingletonOnce<IApplicationStore, ApplicationStore>();
containerRegistry.RegisterSingletonOnce<IEventAggregator, EventAggregator>();
Expand All @@ -32,17 +32,17 @@ public static void RegisterRequiredTypes(this IContainerRegistry containerRegist
containerRegistry.RegisterSingletonOnce<IModuleManager, ModuleManager>();
containerRegistry.RegisterSingletonOnce<IModuleInitializer, ModuleInitializer>();
containerRegistry.RegisterSingletonOnce<IDialogService, DialogService>();
//containerRegistry.RegisterScoped<INavigationService, ErrorReportingNavigationService>(NavigationServiceName);
containerRegistry.Register<INavigationService, ErrorReportingNavigationService>(NavigationServiceName);
containerRegistry.RegisterScoped<INavigationService, ErrorReportingNavigationService>();
var isRegistered = containerRegistry.IsRegistered<INavigationService>(NavigationServiceName);
}

public static void RegisterPrismCoreServices(this IServiceCollection services)
{
services.RegisterSingletonIfNotRegistered<ILogger, ConsoleLoggingService>();
services.RegisterSingletonIfNotRegistered<ILoggerFacade>(sp => (ILogger)sp.GetService(typeof(ILogger)));
services.RegisterSingletonIfNotRegistered<IAnalyticsService>(sp => (ILogger)sp.GetService(typeof(ILogger)));
services.RegisterSingletonIfNotRegistered<ICrashesService>(sp => (ILogger)sp.GetService(typeof(ILogger)));
services.RegisterSingletonIfNotRegistered<IAggregableLogger, ConsoleLoggingService>();
services.RegisterSingletonIfNotRegistered<IAnalyticsService>(sp => (IAggregableLogger)sp.GetService(typeof(IAggregableLogger)));
services.RegisterSingletonIfNotRegistered<ICrashesService>(sp => (IAggregableLogger)sp.GetService(typeof(IAggregableLogger)));
services.RegisterSingletonIfNotRegistered<ILogger>(sp => (IAggregableLogger)sp.GetService(typeof(IAggregableLogger)));
services.RegisterSingletonIfNotRegistered<IEventAggregator, EventAggregator>();
services.RegisterSingletonIfNotRegistered<IModuleCatalog, ModuleCatalog>();
services.RegisterSingletonIfNotRegistered<IModuleManager, ModuleManager>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,8 @@ public class ErrorReportingNavigationService : PageNavigationService
public ErrorReportingNavigationService(IContainerExtension container,
IApplicationProvider applicationProvider,
IPageBehaviorFactory pageBehaviorFactory,
ILoggerFacade logger,
IEventAggregator eventAggregator)
: base(container, applicationProvider, pageBehaviorFactory, logger)
: base(container, applicationProvider, pageBehaviorFactory)
{
EventAggregator = eventAggregator;
}
Expand Down
4 changes: 2 additions & 2 deletions src/Prism.Forms.Extended/Prism.Forms.Extended.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Prism.Forms" Version="8.0.0.1740-pre" />
<PackageReference Include="Prism.Plugin.Logging.Abstractions" Version="7.2.0.1114" />
<PackageReference Include="Prism.Forms" Version="8.0.0.1850-pre" />
<PackageReference Include="Prism.Plugin.Logging.Abstractions" Version="8.0.9-beta" />
</ItemGroup>

<ItemGroup>
Expand Down
3 changes: 1 addition & 2 deletions src/Prism.Forms.Extended/PrismApplication.android.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,8 @@ protected override void Initialize()
base.Initialize();

Logger = Container.Resolve<ILogger>();
Log.Listeners.Add(Container.Resolve<FormsLogListener>());
Log.Listeners.Add(new FormsLogListener(Logger));
Container.Resolve<IEventAggregator>().GetEvent<NavigationErrorEvent>().Subscribe(OnNavigationError);
ConfigureAggregateLogger(Container.Resolve<IAggregateLogger>(), Container);
}

private void AndroidEnvironment_UnhandledExceptionRaiser(object sender, RaiseThrowableEventArgs args)
Expand Down
16 changes: 1 addition & 15 deletions src/Prism.Forms.Extended/PrismApplication.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,10 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization.Json;
using System.Text;
using System.Threading.Tasks;
using Prism.Container.Extensions;
using Prism.Events;
using Prism.Forms.Extended.ViewModels;
using Prism.Ioc;
Expand All @@ -34,15 +32,11 @@ protected PrismApplication(IPlatformInitializer platformInitializer) : base(plat
{
}

protected PrismApplication(IPlatformInitializer platformInitializer, bool setFormsDependencyResolver) : base(platformInitializer, setFormsDependencyResolver)
{
}

public ILogger Logger { get; private set; }

protected IModuleCatalog ModuleCatalog { get; private set; }

protected override sealed void RegisterRequiredTypes(IContainerRegistry containerRegistry)
protected override void RegisterRequiredTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterRequiredTypes();
ViewModelLocationProvider.Register<TabbedPage, DefaultViewModel>();
Expand All @@ -53,14 +47,6 @@ protected override IContainerExtension CreateContainerExtension()
return ContainerLocator.Current ?? throw new NullReferenceException("Call PrismContainerExtension.Init() prior to initializing PrismApplication");
}

protected virtual void ConfigureAggregateLogger(IAggregateLogger aggregateLogger, IContainerProvider container)
{
if(!aggregateLogger.Loggers.Any())
{
aggregateLogger.AddLogger(container.Resolve<ConsoleLoggingService>());
}
}

protected sealed override void InitializeModules()
{
if (ModuleCatalog is null)
Expand Down
3 changes: 1 addition & 2 deletions src/Prism.Forms.Extended/PrismApplication.iosmac.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,8 @@ protected override void Initialize()
base.Initialize();

Logger = Container.Resolve<ILogger>();
Log.Listeners.Add(Container.Resolve<FormsLogListener>());
Log.Listeners.Add(new FormsLogListener(Logger));
Container.Resolve<IEventAggregator>().GetEvent<NavigationErrorEvent>().Subscribe(OnNavigationError);
ConfigureAggregateLogger(Container.Resolve<IAggregateLogger>(), Container);
}

private void Runtime_MarshalObjectiveCException(object sender, MarshalObjectiveCExceptionEventArgs args)
Expand Down
3 changes: 1 addition & 2 deletions src/Prism.Forms.Extended/PrismApplication.netstandard.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,8 @@ protected override void Initialize()
base.Initialize();

Logger = Container.Resolve<ILogger>();
Log.Listeners.Add(Container.Resolve<FormsLogListener>());
Log.Listeners.Add(new FormsLogListener(Logger));
Container.Resolve<IEventAggregator>().GetEvent<NavigationErrorEvent>().Subscribe(OnNavigationError);
ConfigureAggregateLogger(Container.Resolve<IAggregateLogger>(), Container);
}
}
}
26 changes: 0 additions & 26 deletions src/Prism.Forms.Extended/PrismApplicationBaseExtended.cs

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
using System;
using System.Linq;
using Microsoft.Extensions.DependencyInjection;

namespace Prism.Microsoft.DependencyInjection.Extensions
{
internal class ConcreteAwareOverrideProvider : IServiceProvider
{
private IServiceProvider _rootProvider { get; }
private IServiceCollection _services { get; }
private (Type type, object instance)[] _overrides { get; }

public ConcreteAwareOverrideProvider(IServiceProvider serviceProvider, IServiceCollection services, (Type type, object instance)[] overrides)
{
_rootProvider = serviceProvider;
_overrides = overrides;
}

public object GetService(Type serviceType)
{
if (!serviceType.IsAbstract && serviceType.IsClass && serviceType != typeof(object))
{
return BuildInstance(serviceType);
}

var serviceDescriptor = _services.LastOrDefault(x => x.ServiceType == serviceType);

if (serviceDescriptor?.ImplementationType is null)
return _rootProvider.GetService(serviceType);

var implType = serviceDescriptor.ImplementationType;
return BuildInstance(implType);
}

private object BuildInstance(Type implType)
{
var constructors = implType.GetConstructors();

if (constructors is null || !constructors.Any())
return Activator.CreateInstance(implType);

var ctor = constructors.OrderByDescending(x => x.GetParameters().Length).First();
var parameters = ctor.GetParameters().Select(x =>
{
(var t, var instance) = _overrides.FirstOrDefault(o => x.ParameterType == o.type);
if (t != null)
{
return instance;
}
return _rootProvider.GetService(x.ParameterType);
}).ToArray();

return ctor.Invoke(parameters);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,19 @@ namespace Prism.Microsoft.DependencyInjection
{
public class ConcreteAwareServiceProvider : IServiceProvider
{
private bool _isScoped { get; }

public ConcreteAwareServiceProvider(IServiceProvider serviceProvider)
{
ServiceProvider = serviceProvider;
}

public ConcreteAwareServiceProvider(IServiceScope serviceScope)
{
ServiceProvider = serviceScope.ServiceProvider;
_isScoped = true;
}

public IServiceProvider ServiceProvider { get; }

public object GetService(Type serviceType) =>
Expand All @@ -22,6 +30,9 @@ private object GetConcreteImplementation(Type serviceType)

if (serviceType.IsClass)
{
if (_isScoped)
BuildConcreteImplementation(serviceType);

PrismContainerExtension.Current.Register(serviceType, serviceType);
var sp = PrismContainerExtension.Current.ServiceCollection().BuildServiceProvider();
return sp.GetService(serviceType);
Expand All @@ -34,5 +45,18 @@ private object GetConcreteImplementation(Type serviceType)

return null;
}

private object BuildConcreteImplementation(Type serviceType)
{
var constructors = serviceType.GetConstructors();

if (!constructors.Any())
return Activator.CreateInstance(serviceType);

var ctor = constructors.OrderByDescending(x => x.GetParameters().Length).First();

var parameters = ctor.GetParameters().Select(p => GetService(p.ParameterType)).ToArray();
return ctor.Invoke(parameters);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@ public class ConcreteAwareServiceScope : IServiceScope
public ConcreteAwareServiceScope(IServiceScope serviceScope)
{
_serviceScope = serviceScope;
ServiceProvider = new ConcreteAwareServiceProvider(_serviceScope.ServiceProvider); ;
}

public IServiceProvider ServiceProvider => _serviceScope.ServiceProvider;
public IServiceProvider ServiceProvider { get; }

#region IDisposable Support
private bool disposedValue = false; // To detect redundant calls
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<TargetFramework>netstandard2.0</TargetFramework>
<PackageTags>prism di iserviceprovider iservicecollection microsoft-dependencyinjection</PackageTags>
<Authors>dansiegel</Authors>
<Description>Prism Container Extensions for the Microsoft.Extensions.DependencyInjection implementations of IServiceCollection / IServiceProvider</Description>
<Description>Prism Container Extensions for the Microsoft.Extensions.DependencyInjection implementations of IServiceCollection / IServiceProvider. NOTE: This is an EXPERIMENTAL Container! While this may basic basic tests, this container may still have unknown issues as the Microsoft.Extensions.DependencyInjection package inheriently does not support either Named Types or Container Mutability.</Description>
</PropertyGroup>

<ItemGroup>
Expand Down
Loading

0 comments on commit 3b7915e

Please sign in to comment.