Skip to content

Commit 0e2b868

Browse files
committed
Implement SceneServiceInjectionRequest
1 parent 2873d22 commit 0e2b868

5 files changed

Lines changed: 110 additions & 0 deletions

File tree

KludgeBox/DI/Requests/RequestsScanner.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using KludgeBox.DI.Requests.MpSyncInjection;
55
using KludgeBox.DI.Requests.NotNullCheck;
66
using KludgeBox.DI.Requests.ParentInjection;
7+
using KludgeBox.DI.Requests.SceneServiceInjection;
78
using KludgeBox.Reflection.Access;
89

910
namespace KludgeBox.DI.Requests;
@@ -21,6 +22,7 @@ public static RequestsScanner CreateDefault()
2122
{
2223
var scanner = new RequestsScanner();
2324
scanner.RegisterRequestScanner(new LoggerInjectionRequestScanner());
25+
scanner.RegisterRequestScanner(new SceneServiceInjectionRequestScanner());
2426
scanner.RegisterRequestScanner(new DependencyCreationRequestScanner());
2527
scanner.RegisterRequestScanner(new ChildInjectionRequestScanner());
2628
scanner.RegisterRequestScanner(new ParentInjectionRequestScanner());
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
namespace KludgeBox.DI.Requests.SceneServiceInjection;
2+
3+
public interface ISceneServiceProvider
4+
{
5+
/// <summary>
6+
/// Returns service of specified type if found in scene or null.
7+
/// </summary>
8+
/// <param name="serviceType">Type of required service</param>
9+
/// <returns></returns>
10+
object GetService(Type serviceType);
11+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
using Godot;
2+
using KludgeBox.Reflection.Access;
3+
4+
namespace KludgeBox.DI.Requests.SceneServiceInjection;
5+
6+
public class SceneServiceInjectionRequest : IProcessingRequest
7+
{
8+
9+
private readonly IMemberAccessor _memberAccessor;
10+
private readonly Type _serviceType;
11+
12+
public SceneServiceInjectionRequest(IMemberAccessor memberAccessor, Type serviceType)
13+
{
14+
_memberAccessor = memberAccessor;
15+
_serviceType = serviceType;
16+
}
17+
18+
19+
public void ProcessOnInstance(object instance)
20+
{
21+
var nodeInstance = (Node)instance; // All checks are done in scanner
22+
var serviceType = _serviceType ?? _memberAccessor.ValueType;
23+
var service = GetService(serviceType, nodeInstance);
24+
25+
if (service is null)
26+
{
27+
throw new InvalidOperationException($"Service of type {serviceType} not found for node {nodeInstance.GetPath()}@{nodeInstance.GetType().Name}.");
28+
}
29+
30+
_memberAccessor.SetValue(instance, service);
31+
}
32+
33+
private object GetService(Type serviceType, Node possibleServiceProvider)
34+
{
35+
object foundService = null;
36+
37+
if (possibleServiceProvider is ISceneServiceProvider serviceProvider)
38+
{
39+
foundService = serviceProvider.GetService(serviceType);
40+
}
41+
42+
if (foundService is not null)
43+
{
44+
return foundService;
45+
}
46+
47+
var parent = possibleServiceProvider.GetParent();
48+
if (!parent.IsValid())
49+
{
50+
return null;
51+
}
52+
53+
return GetService(serviceType, parent);
54+
}
55+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
using Godot;
2+
using KludgeBox.Logging;
3+
using KludgeBox.Reflection.Access;
4+
using Serilog;
5+
6+
namespace KludgeBox.DI.Requests.SceneServiceInjection;
7+
8+
public class SceneServiceInjectionRequestScanner : IProcessingRequestScanner
9+
{
10+
11+
private readonly ILogger _log = LogFactory.GetForStatic<SceneServiceInjectionRequestScanner>();
12+
public bool TryGetRequest(IMemberAccessor accessor, out IProcessingRequest injectionRequest)
13+
{
14+
if (!accessor.TryGetAttribute<SceneServiceAttribute>(out var attribute))
15+
{
16+
injectionRequest = null;
17+
return false;
18+
}
19+
20+
if (!accessor.Member.ReflectedType.IsAssignableTo(typeof(Node)))
21+
{
22+
injectionRequest = null;
23+
return false;
24+
}
25+
26+
injectionRequest = new SceneServiceInjectionRequest(accessor,attribute.ServiceType);
27+
return true;
28+
}
29+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
namespace KludgeBox.DI.Requests.SceneServiceInjection;
2+
3+
public class SceneServiceAttribute : Attribute
4+
{
5+
public Type ServiceType { get; }
6+
7+
public SceneServiceAttribute() : this(null) { }
8+
9+
public SceneServiceAttribute(Type serviceType)
10+
{
11+
ServiceType = serviceType;
12+
}
13+
}

0 commit comments

Comments
 (0)