dansiegel/Prism.Container.Extensions

[Shiny.Prism] Optional dependencies resolutions not handled gracefully

aritchie opened this issue · 2 comments

Shiny delegates are always tested to see if they can be resolved using the IServiceProvider.GetService which returns default/null if not found on the default MSFT container (and autofac lol).

DryIoc throws an exception if the dependency is not satisfied. I am taking steps on my end, but this should likely be standard functionality in your library as well.

To reproduce:

  1. Do standard shiny setup
  2. Use something like GPS or Notifications (services.UseGps/services.UseNotifications) without the delegate. When a GPS or notification events fire, Shiny will encounter an error during resolution.

FYI - platform does not matter in this case.

Here is the full error from a notification entry for a stack trace (ignore the isregistration check - it isn't working on my end yet and that will be the first part of the defense):

[EXCEPTION] Prism.Ioc.ContainerResolutionException: An unexpected error occurred while resolving 'Shiny.Notifications.INotificationDelegate' ---> DryIoc.ContainerException: Unable to resolve Shiny.Notifications.INotificationDelegate IsResolutionCall
from Container without Scope
with Rules with {AutoConcreteTypeResolution} and without {ThrowOnRegisteringDisposableTransient, UseFastExpressionCompilerIfPlatformSupported}
with Made={FactoryMethod=ConstructorWithResolvableArguments}
Where no service registrations found
and no dynamic registrations found in 0 of Rules.DynamicServiceProviders
and nothing found in 1 of Rules.UnknownServiceResolvers
at DryIoc.Throw.It (System.Int32 error, System.Object arg0, System.Object arg1, System.Object arg2, System.Object arg3) [0x00012] in :0
at DryIoc.Container.TryThrowUnableToResolve (DryIoc.Request request) [0x000a9] in :0
at DryIoc.Cont
ainer.DryIoc.IContainer.ResolveFactory (DryIoc.Request request) [0x00072] in :0
at DryIoc.Container.ResolveAndCacheFactoryDelegate (System.Type serviceType, DryIoc.IfUnresolved ifUnresolved) [0x00021] in :0
at DryIoc.Container.DryIoc.IResolver.Resolve (System.Type serviceType, DryIoc.IfUnresolved ifUnresolved) [0x00020] in :0
at DryIoc.Container.DryIoc.IResolver.Resolve (System.Type serviceType, System.Object serviceKey, DryIoc.IfUnresolved ifUnresolved, System.Type requiredServiceType, DryIoc.Request preResolveParent, System.Object[] args) [0x00040] in :0
at DryIoc.Resolver.Resolve (DryIoc.IResolver resolver, System.Type serviceType, System.Object[] args, DryIoc.IfUnresolved ifUnresolved, System.Type requiredServiceType, System.Object serviceKey) [0x00000] in :0
at Prism.DryIoc.PrismContainerExtension.Resolve (System.Type type
, System.ValueTuple2[System.Type,System.Object][] parameters) [0x00000] in d:\a\1\s\src\Prism.DryIoc.Extensions\PrismContainerExtension.cs:217 --- End of inner exception stack trace --- at Prism.DryIoc.PrismContainerExtension.Resolve (System.Type type, System.ValueTuple2[System.Type,System.Object][] parameters) [0x0003d] in d:\a\1\s\src\Prism.DryIoc.Extensions\PrismContainerExtension.cs:221
at Prism.DryIoc.PrismContainerExtension.Resolve (System.Type type) [0x00000] in d:\a\1\s\src\Prism.DryIoc.Extensions\PrismContainerExtension.cs:208
at Prism.DryIoc.PrismContainerExtension.GetService (System.Type serviceType) [0x00000] in d:\a\1\s\src\Prism.DryIoc.Extensions\PrismContainerExtension.cs:237
at Shiny.ServiceExtensions.IsRegistered[T] (System.IServiceProvider services) [0x00000] in d:\a\1\s\src\Shiny.Core\Extensions_Services.cs:163
at Shiny.ServiceExtensions.Resolve[T] (System.IServiceProvider serviceProvider, System.Boolean requiredService) [0x00000] in d:\a\1\s\src\Shiny.Core\Extensions_Se
rvices.cs:22
at Shiny.ShinyHost.Resolve[T] () [0x00000] in d:\a\1\s\src\Shiny.Core\ShinyHost.cs:28
at Shiny.Notifications.ShinyNotificationDelegate+<>c.<.ctor>b__4_0 () [0x00000] in d:\a\1\s\src\Shiny.Notifications\Platforms\iOS\ShinyNotificationDelegate.cs:11
at System.Lazy`1[T].ViaFactory (System.Threading.LazyThreadSafetyMode mode) [0x0001c] in /Library/Frameworks/Xamarin.iOS.framework/Versions/12.14.0.114/src/Xamarin.iOS/external/corefx/src/Common/src/CoreLib/System/Lazy.cs:327
--- End of stack trace from previous location where exception was thrown ---

Per our discussion we will be changing some behavior in GetService to return null if the service is not registered otherwise we will allow exceptions to be thrown if there is an error in the ctor for example.

this is fixed and will be in the next release