chore: Remove the [InterfaceVersion] attribute (#1844)

This commit is contained in:
KazWolfe 2024-06-16 04:01:17 -07:00 committed by GitHub
parent 7ddc5d82ca
commit 0c8c4bfdbf
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
41 changed files with 20 additions and 164 deletions

View file

@ -1,22 +0,0 @@
namespace Dalamud.IoC.Internal;
/// <summary>
/// This attribute represents the current version of a module that is loaded in the Service Locator.
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface)]
internal class InterfaceVersionAttribute : Attribute
{
/// <summary>
/// Initializes a new instance of the <see cref="InterfaceVersionAttribute"/> class.
/// </summary>
/// <param name="version">The current version.</param>
public InterfaceVersionAttribute(string version)
{
this.Version = new(version);
}
/// <summary>
/// Gets the service version.
/// </summary>
public Version Version { get; }
}

View file

@ -16,14 +16,8 @@ internal class ObjectInstance
public ObjectInstance(Task<WeakReference> instanceTask, Type type)
{
this.InstanceTask = instanceTask;
this.Version = type.GetCustomAttribute<InterfaceVersionAttribute>();
}
/// <summary>
/// Gets the current version of the instance, if it exists.
/// </summary>
public InterfaceVersionAttribute? Version { get; }
/// <summary>
/// Gets a reference to the underlying instance.
/// </summary>

View file

@ -95,31 +95,18 @@ internal class ServiceContainer : IServiceProvider, IServiceType
}
// validate dependency versions (if they exist)
var parameters = ctor.GetParameters().Select(p =>
{
var parameterType = p.ParameterType;
var requiredVersion = p.GetCustomAttribute(typeof(RequiredVersionAttribute)) as RequiredVersionAttribute;
return (parameterType, requiredVersion);
}).ToList();
var versionCheck = parameters.All(p => CheckInterfaceVersion(p.requiredVersion, p.parameterType));
if (!versionCheck)
{
Log.Error("Failed to create {TypeName}, a RequestedVersion could not be satisfied", objectType.FullName!);
return null;
}
var parameterTypes = ctor.GetParameters().Select(p => p.ParameterType).ToList();
var resolvedParams =
await Task.WhenAll(
parameters
.Select(async p =>
parameterTypes
.Select(async type =>
{
var service = await this.GetService(p.parameterType, scopeImpl, scopedObjects);
var service = await this.GetService(type, scopeImpl, scopedObjects);
if (service == null)
{
Log.Error("Requested ctor service type {TypeName} was not available (null)", p.parameterType.FullName!);
Log.Error("Requested ctor service type {TypeName} was not available (null)", type.FullName!);
}
return service;
@ -160,31 +147,18 @@ internal class ServiceContainer : IServiceProvider, IServiceType
var objectType = instance.GetType();
var props = objectType.GetProperties(BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public |
BindingFlags.NonPublic).Where(x => x.GetCustomAttributes(typeof(PluginServiceAttribute)).Any()).Select(
propertyInfo =>
{
var requiredVersion = propertyInfo.GetCustomAttribute(typeof(RequiredVersionAttribute)) as RequiredVersionAttribute;
return (propertyInfo, requiredVersion);
}).ToArray();
var versionCheck = props.All(x => CheckInterfaceVersion(x.requiredVersion, x.propertyInfo.PropertyType));
if (!versionCheck)
{
Log.Error("Failed to create {TypeName}, a RequestedVersion could not be satisfied", objectType.FullName!);
return false;
}
BindingFlags.NonPublic).Where(x => x.GetCustomAttributes(typeof(PluginServiceAttribute)).Any()).ToArray();
foreach (var prop in props)
{
var service = await this.GetService(prop.propertyInfo.PropertyType, scopeImpl, publicScopes);
var service = await this.GetService(prop.PropertyType, scopeImpl, publicScopes);
if (service == null)
{
Log.Error("Requested service type {TypeName} was not available (null)", prop.propertyInfo.PropertyType.FullName!);
Log.Error("Requested service type {TypeName} was not available (null)", prop.PropertyType.FullName!);
return false;
}
prop.propertyInfo.SetValue(instance, service);
prop.SetValue(instance, service);
}
return true;
@ -199,29 +173,6 @@ internal class ServiceContainer : IServiceProvider, IServiceType
/// <inheritdoc/>
object? IServiceProvider.GetService(Type serviceType) => this.GetSingletonService(serviceType);
private static bool CheckInterfaceVersion(RequiredVersionAttribute? requiredVersion, Type parameterType)
{
// if there's no required version, ignore it
if (requiredVersion == null)
return true;
// if there's no requested version, ignore it
var declVersion = parameterType.GetCustomAttribute<InterfaceVersionAttribute>();
if (declVersion == null)
return true;
if (declVersion.Version == requiredVersion.Version)
return true;
Log.Error(
"Requested version {ReqVersion} does not match the implemented version {ImplVersion} for param type {ParamType}",
requiredVersion.Version,
declVersion.Version,
parameterType.FullName!);
return false;
}
private async Task<object?> GetService(Type serviceType, ServiceScopeImpl? scope, object[] scopedObjects)
{
if (this.interfaceToTypeMap.TryGetValue(serviceType, out var implementingType))

View file

@ -1,22 +0,0 @@
namespace Dalamud.IoC;
/// <summary>
/// This attribute indicates the version of a service module that is required for the plugin to load.
/// </summary>
[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property)]
public class RequiredVersionAttribute : Attribute
{
/// <summary>
/// Initializes a new instance of the <see cref="RequiredVersionAttribute"/> class.
/// </summary>
/// <param name="version">The required version.</param>
public RequiredVersionAttribute(string version)
{
this.Version = new(version);
}
/// <summary>
/// Gets the required version.
/// </summary>
public Version Version { get; }
}