diff --git a/Dalamud/IoC/Internal/ServiceContainer.cs b/Dalamud/IoC/Internal/ServiceContainer.cs
index feac634f3..db748303e 100644
--- a/Dalamud/IoC/Internal/ServiceContainer.cs
+++ b/Dalamud/IoC/Internal/ServiceContainer.cs
@@ -12,6 +12,9 @@ namespace Dalamud.IoC.Internal;
///
/// A simple singleton-only IOC container that provides (optional) version-based dependency resolution.
+///
+/// This is only used to resolve dependencies for plugins.
+/// Dalamud services are constructed via Service{T}.ConstructObject at the moment.
///
internal class ServiceContainer : IServiceProvider, IServiceType
{
@@ -31,7 +34,7 @@ public ServiceContainer()
/// Register a singleton object of any type into the current IOC container.
///
/// The existing instance to register in the container.
- /// The interface to register.
+ /// The type to register.
public void RegisterSingleton(Task instance)
{
if (instance == null)
@@ -40,19 +43,27 @@ public void RegisterSingleton(Task instance)
}
this.instances[typeof(T)] = new(instance.ContinueWith(x => new WeakReference(x.Result)), typeof(T));
+ this.RegisterInterfaces(typeof(T));
+ }
- var resolveViaTypes = typeof(T)
- .GetCustomAttributes()
- .OfType()
- .Select(x => x.GetType().GetGenericArguments().First());
+ ///
+ /// Register the interfaces that can resolve this type.
+ ///
+ /// The type to register.
+ public void RegisterInterfaces(Type type)
+ {
+ var resolveViaTypes = type
+ .GetCustomAttributes()
+ .OfType()
+ .Select(x => x.GetType().GetGenericArguments().First());
foreach (var resolvableType in resolveViaTypes)
{
- Log.Verbose("=> {InterfaceName} provides for {TName}", resolvableType.FullName ?? "???", typeof(T).FullName ?? "???");
+ Log.Verbose("=> {InterfaceName} provides for {TName}", resolvableType.FullName ?? "???", type.FullName ?? "???");
Debug.Assert(!this.interfaceToTypeMap.ContainsKey(resolvableType), "A service already implements this interface, this is not allowed");
- Debug.Assert(typeof(T).IsAssignableTo(resolvableType), "Service does not inherit from indicated ResolveVia type");
+ Debug.Assert(type.IsAssignableTo(resolvableType), "Service does not inherit from indicated ResolveVia type");
- this.interfaceToTypeMap[resolvableType] = typeof(T);
+ this.interfaceToTypeMap[resolvableType] = type;
}
}
@@ -95,18 +106,7 @@ await Task.WhenAll(
parameters
.Select(async p =>
{
- if (p.parameterType.GetCustomAttribute() != null)
- {
- if (scopeImpl == null)
- {
- Log.Error("Failed to create {TypeName}, depends on scoped service but no scope", objectType.FullName!);
- return null;
- }
-
- return await scopeImpl.CreatePrivateScopedObject(p.parameterType, scopedObjects);
- }
-
- var service = await this.GetService(p.parameterType, scopedObjects);
+ var service = await this.GetService(p.parameterType, scopeImpl, scopedObjects);
if (service == null)
{
@@ -168,22 +168,7 @@ public async Task InjectProperties(object instance, object[] publicScopes,
foreach (var prop in props)
{
- object service = null;
-
- if (prop.propertyInfo.PropertyType.GetCustomAttribute() != null)
- {
- if (scopeImpl == null)
- {
- Log.Error("Failed to create {TypeName}, depends on scoped service but no scope", objectType.FullName!);
- }
- else
- {
- service = await scopeImpl.CreatePrivateScopedObject(prop.propertyInfo.PropertyType, publicScopes);
- }
- }
-
- service ??= await this.GetService(prop.propertyInfo.PropertyType, publicScopes);
-
+ var service = await this.GetService(prop.propertyInfo.PropertyType, scopeImpl, publicScopes);
if (service == null)
{
Log.Error("Requested service type {TypeName} was not available (null)", prop.propertyInfo.PropertyType.FullName!);
@@ -203,7 +188,7 @@ public async Task InjectProperties(object instance, object[] publicScopes,
public IServiceScope GetScope() => new ServiceScopeImpl(this);
///
- object? IServiceProvider.GetService(Type serviceType) => this.GetService(serviceType);
+ object? IServiceProvider.GetService(Type serviceType) => this.GetSingletonService(serviceType);
private static bool CheckInterfaceVersion(RequiredVersionAttribute? requiredVersion, Type parameterType)
{
@@ -228,9 +213,23 @@ private static bool CheckInterfaceVersion(RequiredVersionAttribute? requiredVers
return false;
}
- private async Task