From 11efdf642053fad2ecdb83eab1892024be427621 Mon Sep 17 00:00:00 2001
From: Alon Talmi <130899578+AlonTalmi@users.noreply.github.com>
Date: Thu, 30 Nov 2023 16:42:14 +0100
Subject: [PATCH 1/3] TryRsolve
---
.../Assets/VContainer/Runtime/Container.cs | 51 +++++++++++++++++--
.../Runtime/IObjectResolverExtensions.cs | 24 +++++++++
.../Runtime/Unity/EntryPointDispatcher.cs | 9 +---
3 files changed, 73 insertions(+), 11 deletions(-)
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++)
From c0bcc1b8f56acf3c7055bf26ef71b72ab95229c9 Mon Sep 17 00:00:00 2001
From: Alon Talmi <130899578+AlonTalmi@users.noreply.github.com>
Date: Thu, 30 Nov 2023 16:42:29 +0100
Subject: [PATCH 2/3] Added Unit tests
---
VContainer/Assets/Tests/ContainerTest.cs | 67 ++++++++++++++++++++++--
1 file changed, 63 insertions(+), 4 deletions(-)
diff --git a/VContainer/Assets/Tests/ContainerTest.cs b/VContainer/Assets/Tests/ContainerTest.cs
index ad8247d5..a9320011 100644
--- a/VContainer/Assets/Tests/ContainerTest.cs
+++ b/VContainer/Assets/Tests/ContainerTest.cs
@@ -328,7 +328,7 @@ public void RegisterFromFunc()
Assert.That(resolved, Is.InstanceOf());
Assert.That(resolved.Service2, Is.InstanceOf());
}
-
+
[Test]
public void RegisterValueTypeFromFunc()
{
@@ -442,7 +442,7 @@ public void RegisterWithParameter()
var resolved = container.Resolve();
Assert.That(resolved.Service2, Is.EqualTo(paramValue));
}
-
+
{
var builder = new ContainerBuilder();
builder.Register(Lifetime.Scoped);
@@ -601,8 +601,10 @@ public void OnContainerDisposeCallback()
builder.Register(Lifetime.Scoped);
builder.Register(Lifetime.Scoped);
- builder.RegisterDisposeCallback(resolver => resolvedJustBeforeDispose = resolver.Resolve());
- builder.RegisterDisposeCallback(resolver => resolvedJustBeforeDispose2 = resolver.Resolve());
+ builder.RegisterDisposeCallback(resolver =>
+ resolvedJustBeforeDispose = resolver.Resolve());
+ builder.RegisterDisposeCallback(resolver =>
+ resolvedJustBeforeDispose2 = resolver.Resolve());
var container = builder.Build();
@@ -614,5 +616,62 @@ public void OnContainerDisposeCallback()
Assert.That(resolvedJustBeforeDispose, Is.Not.Null);
Assert.That(resolvedJustBeforeDispose2, Is.Not.Null);
}
+
+ [Test]
+ public void TryResolveTransient()
+ {
+ var builder = new ContainerBuilder();
+ builder.Register(Lifetime.Transient);
+
+ var container = builder.Build();
+
+ Assert.That(container.TryResolve(out var obj1), Is.True);
+ Assert.That(container.TryResolve(out var obj2), Is.True);
+ Assert.That(container.TryResolve(out var obj3), Is.False);
+
+ Assert.That(obj1, Is.TypeOf());
+ Assert.That(obj2, Is.TypeOf());
+ Assert.That(obj1, Is.Not.EqualTo(obj2));
+ Assert.That(obj3, Is.Null);
+ }
+
+ [Test]
+ public void TryResolveSingleton()
+ {
+ var builder = new ContainerBuilder();
+ builder.Register(Lifetime.Singleton);
+
+ var container = builder.Build();
+ Assert.That(container.TryResolve(out var obj1), Is.True);
+ Assert.That(container.TryResolve(out var obj2), Is.True);
+ Assert.That(container.TryResolve(out var obj3), Is.False);
+
+ Assert.That(obj1, Is.TypeOf());
+ Assert.That(obj2, Is.TypeOf());
+ Assert.That(obj1, Is.EqualTo(obj2));
+ Assert.That(obj3, Is.Null);
+ }
+
+ [Test]
+ public void TryResolveScoped()
+ {
+ var builder = new ContainerBuilder();
+ builder.Register(Lifetime.Scoped);
+
+ var container = builder.Build();
+ Assert.That(container.TryResolve(out var obj1), Is.True);
+ Assert.That(container.TryResolve(out var obj2), Is.True);
+ Assert.That(container.TryResolve(out var obj3), Is.False);
+
+ Assert.That(obj1, Is.TypeOf());
+ Assert.That(obj2, Is.TypeOf());
+ Assert.That(obj1, Is.EqualTo(obj2));
+ Assert.That(obj3, Is.Null);
+
+ container.Dispose();
+
+ Assert.That(obj1.Disposed, Is.True);
+>>>>>>> 1d6258b (Added Unit tests):VContainer/Assets/VContainer/Tests/ContainerTest.cs
+ }
}
}
From 921ec3dde369c7d19fc862772b7bcb57a2b64288 Mon Sep 17 00:00:00 2001
From: hadashiA
Date: Thu, 4 Apr 2024 13:38:51 +0900
Subject: [PATCH 3/3] Tweaks
---
VContainer/Assets/Tests/ContainerTest.cs | 1 -
.../Assets/VContainer/Runtime/Container.cs | 28 +++++++++----------
2 files changed, 14 insertions(+), 15 deletions(-)
diff --git a/VContainer/Assets/Tests/ContainerTest.cs b/VContainer/Assets/Tests/ContainerTest.cs
index a9320011..635d6618 100644
--- a/VContainer/Assets/Tests/ContainerTest.cs
+++ b/VContainer/Assets/Tests/ContainerTest.cs
@@ -671,7 +671,6 @@ public void TryResolveScoped()
container.Dispose();
Assert.That(obj1.Disposed, Is.True);
->>>>>>> 1d6258b (Added Unit tests):VContainer/Assets/VContainer/Tests/ContainerTest.cs
}
}
}
diff --git a/VContainer/Assets/VContainer/Runtime/Container.cs b/VContainer/Assets/VContainer/Runtime/Container.cs
index 648668ce..e7d0b925 100644
--- a/VContainer/Assets/VContainer/Runtime/Container.cs
+++ b/VContainer/Assets/VContainer/Runtime/Container.cs
@@ -18,7 +18,7 @@ public interface IObjectResolver : IDisposable
/// This version of resolve looks for all of scopes
///
object Resolve(Type type);
-
+
///
/// Try resolve from type
///
@@ -35,7 +35,9 @@ public interface IObjectResolver : IDisposable
/// This version of resolve will look for instances from only the registration information already founds.
///
object Resolve(Registration registration);
+
IScopedObjectResolver CreateScope(Action installation = null);
+
void Inject(object instance);
bool TryGetRegistration(Type type, out Registration registration);
}
@@ -82,7 +84,14 @@ internal ScopedContainer(
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public object Resolve(Type type) => Resolve(FindRegistration(type));
+ public object Resolve(Type type)
+ {
+ if (TryFindRegistration(type, out var registration))
+ {
+ return Resolve(registration);
+ }
+ throw new VContainerException(type, $"No such registration of type: {type}");
+ }
public bool TryResolve(Type type, out object resolved)
{
@@ -174,15 +183,6 @@ object CreateTrackedInstance(Registration registration)
return instance;
}
- [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)
{
@@ -228,7 +228,7 @@ internal Container(Registry registry, object applicationOrigin = null)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public object Resolve(Type type)
{
- if (registry.TryGet(type, out var registration))
+ if (TryGetRegistration(type, out var registration))
{
return Resolve(registration);
}
@@ -238,12 +238,12 @@ public object Resolve(Type type)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool TryResolve(Type type, out object resolved)
{
- if (registry.TryGet(type, out var registration))
+ if (TryGetRegistration(type, out var registration))
{
resolved = Resolve(registration);
return true;
}
-
+
resolved = default;
return false;
}