diff --git a/VContainer/Assets/VContainer/Runtime/Container.cs b/VContainer/Assets/VContainer/Runtime/Container.cs index 639310e3..648668ce 100644 --- a/VContainer/Assets/VContainer/Runtime/Container.cs +++ b/VContainer/Assets/VContainer/Runtime/Container.cs @@ -18,6 +18,15 @@ public interface IObjectResolver : IDisposable /// This version of resolve looks for all of scopes /// object Resolve(Type type); + + /// + /// Try resolve from type + /// + /// + /// This version of resolve looks for all of scopes + /// + /// Successfully resolved + bool TryResolve(Type type, out object resolved); /// /// Resolve from meta with registration @@ -75,6 +84,18 @@ internal ScopedContainer( [MethodImpl(MethodImplOptions.AggressiveInlining)] public object Resolve(Type type) => Resolve(FindRegistration(type)); + public bool TryResolve(Type type, out object resolved) + { + if (TryFindRegistration(type, out var registration)) + { + resolved = Resolve(registration); + return true; + } + + resolved = default; + return false; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public object Resolve(Registration registration) { @@ -155,17 +176,28 @@ object CreateTrackedInstance(Registration registration) [MethodImpl(MethodImplOptions.AggressiveInlining)] internal Registration FindRegistration(Type type) + { + if (TryFindRegistration(type, out var registration)) + return registration; + + throw new VContainerException(type, $"No such registration of type: {type}"); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal bool TryFindRegistration(Type type, out Registration registration) { IScopedObjectResolver scope = this; while (scope != null) { - if (scope.TryGetRegistration(type, out var registration)) + if (scope.TryGetRegistration(type, out registration)) { - return registration; + return true; } scope = scope.Parent; } - throw new VContainerException(type, $"No such registration of type: {type}"); + + registration = default; + return false; } } @@ -203,6 +235,19 @@ public object Resolve(Type type) throw new VContainerException(type, $"No such registration of type: {type}"); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool TryResolve(Type type, out object resolved) + { + if (registry.TryGet(type, out var registration)) + { + resolved = Resolve(registration); + return true; + } + + resolved = default; + return false; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public object Resolve(Registration registration) { diff --git a/VContainer/Assets/VContainer/Runtime/IObjectResolverExtensions.cs b/VContainer/Assets/VContainer/Runtime/IObjectResolverExtensions.cs index cd3b15be..68967d78 100644 --- a/VContainer/Assets/VContainer/Runtime/IObjectResolverExtensions.cs +++ b/VContainer/Assets/VContainer/Runtime/IObjectResolverExtensions.cs @@ -9,6 +9,30 @@ public static class IObjectResolverExtensions [MethodImpl(MethodImplOptions.AggressiveInlining)] public static T Resolve(this IObjectResolver resolver) => (T)resolver.Resolve(typeof(T)); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool TryResolve(this IObjectResolver resolver, out T resolved) + { + if (resolver.TryResolve(typeof(T), out var r)) + { + resolved = (T)r; + return true; + } + + resolved = default; + return false; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static T ResolveOrDefault(this IObjectResolver resolver, T defaultValue = default) + { + if (resolver.TryResolve(typeof(T), out var value)) + { + return (T)value; + } + + return defaultValue; + } + // Using from CodeGen [Preserve] [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/VContainer/Assets/VContainer/Runtime/Unity/EntryPointDispatcher.cs b/VContainer/Assets/VContainer/Runtime/Unity/EntryPointDispatcher.cs index e75f6471..c47d91a4 100644 --- a/VContainer/Assets/VContainer/Runtime/Unity/EntryPointDispatcher.cs +++ b/VContainer/Assets/VContainer/Runtime/Unity/EntryPointDispatcher.cs @@ -22,14 +22,7 @@ public void Dispatch() { PlayerLoopHelper.EnsureInitialized(); - EntryPointExceptionHandler exceptionHandler = null; - try - { - exceptionHandler = container.Resolve(); - } - catch (VContainerException ex) when (ex.InvalidType == typeof(EntryPointExceptionHandler)) - { - } + EntryPointExceptionHandler exceptionHandler = container.ResolveOrDefault(); var initializables = container.Resolve>>().Value; for (var i = 0; i < initializables.Count; i++)