diff --git a/VContainer/Assets/VContainer/Editor/CodeGen/InjectionILGenerator.cs b/VContainer/Assets/VContainer/Editor/CodeGen/InjectionILGenerator.cs index e1503d30..3c282fea 100644 --- a/VContainer/Assets/VContainer/Editor/CodeGen/InjectionILGenerator.cs +++ b/VContainer/Assets/VContainer/Editor/CodeGen/InjectionILGenerator.cs @@ -1,11 +1,14 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.IO; using System.Linq; +using System.Reflection; using Mono.Cecil; using Mono.Cecil.Cil; using Mono.Cecil.Rocks; using Unity.CompilationPipeline.Common.Diagnostics; +using Unity.CompilationPipeline.Common.ILPostProcessing; using MethodAttributes = Mono.Cecil.MethodAttributes; using TypeAttributes = Mono.Cecil.TypeAttributes; using VContainer.Internal; @@ -15,8 +18,11 @@ namespace VContainer.Editor.CodeGen sealed class InjectionILGenerator { readonly ModuleDefinition module; + readonly ICompiledAssembly compiledAssembly; readonly IList targetNamespaces; + Assembly currentAssembly; + TypeReference ObjectResolverTypeRef => objectResolverTypeRef ?? (objectResolverTypeRef = module.ImportReference(typeof(IObjectResolver))); @@ -54,9 +60,13 @@ sealed class InjectionILGenerator MethodReference resolveMethodRef; MethodReference resolveOrParameterMethodRef; - public InjectionILGenerator(ModuleDefinition module, IList targetNamespaces) + public InjectionILGenerator( + ModuleDefinition module, + ICompiledAssembly compiledAssembly, + IList targetNamespaces = null) { this.module = module; + this.compiledAssembly = compiledAssembly; this.targetNamespaces = targetNamespaces; } @@ -70,9 +80,11 @@ public bool TryGenerate(out List diagnosticMessages) foreach (var typeDef in module.Types) { + if (typeDef.FullName == "") continue; + try { - if (TryGenerate(typeDef, diagnosticMessages)) + if (TryGenerateType(typeDef, diagnosticMessages)) { count += 1; } @@ -108,11 +120,46 @@ public bool TryGenerate(out List diagnosticMessages) return false; } - bool TryGenerate(TypeDefinition typeDef, List diagnosticMessages) + bool NeedsInjectType(Type type) + => !type.IsEnum && + !type.IsValueType && + !type.IsInterface && + !(type.IsAbstract && type.IsSealed) && + !typeof(Delegate).IsAssignableFrom(type) && + !typeof(Attribute).IsAssignableFrom(type) && + !type.IsGenericType && + (targetNamespaces == null || + targetNamespaces.Count <= 0 || + targetNamespaces.Contains(type.Namespace)); + + Type GetTypeFromDef(TypeDefinition typeDef) { - var type = Type.GetType($"{typeDef.FullName}, {module.Assembly.FullName}"); + try + { + return Type.GetType($"{typeDef.FullName}, {module.Assembly.FullName}"); + } + catch (FileLoadException) + { + if (currentAssembly == null) + currentAssembly = Assembly.Load(compiledAssembly.InMemoryAssembly.PeData); + return currentAssembly.GetType(typeDef.FullName); + } + } - if (type == null || !NeedsInjectType(type)) + bool TryGenerateType(TypeDefinition typeDef, List diagnosticMessages) + { + var type = GetTypeFromDef(typeDef); + if (type == null) + { + diagnosticMessages.Add(new DiagnosticMessage + { + DiagnosticType = DiagnosticType.Warning, + MessageData = $"Skip IL waving because cant detect type: {typeDef.FullName}" + }); + return false; + } + + if (!NeedsInjectType(type)) return false; InjectTypeInfo injectTypeInfo; @@ -125,7 +172,7 @@ bool TryGenerate(TypeDefinition typeDef, List diagnosticMessa diagnosticMessages.Add(new DiagnosticMessage { DiagnosticType = DiagnosticType.Warning, - MessageData = $"Failed to analyze {type.FullName} : {ex.Message}" + MessageData = $"Failed to analyze {type.FullName} : {ex.GetType()} {ex.Message}" }); return false; } @@ -134,18 +181,6 @@ bool TryGenerate(TypeDefinition typeDef, List diagnosticMessa return true; } - bool NeedsInjectType(Type type) - => !type.IsEnum && - !type.IsValueType && - !type.IsInterface && - !(type.IsAbstract && type.IsSealed) && - !typeof(Delegate).IsAssignableFrom(type) && - !typeof(Attribute).IsAssignableFrom(type) && - !type.IsGenericType && - (targetNamespaces == null || - targetNamespaces.Count <= 0 || - targetNamespaces.Contains(type.Namespace)); - void GenerateInnerInjectorType(TypeDefinition typeDef, InjectTypeInfo injectTypeInfo) { var injectorTypeDef = new TypeDefinition( diff --git a/VContainer/Assets/VContainer/Editor/CodeGen/VContainerILPostProcessor.cs b/VContainer/Assets/VContainer/Editor/CodeGen/VContainerILPostProcessor.cs index c9c4ed39..2477d59b 100644 --- a/VContainer/Assets/VContainer/Editor/CodeGen/VContainerILPostProcessor.cs +++ b/VContainer/Assets/VContainer/Editor/CodeGen/VContainerILPostProcessor.cs @@ -1,5 +1,6 @@ using System.IO; using System.Linq; +using System.Reflection; using Unity.CompilationPipeline.Common.Diagnostics; using Unity.CompilationPipeline.Common.ILPostProcessing; using Mono.Cecil; @@ -26,7 +27,7 @@ public override ILPostProcessResult Process(ICompiledAssembly compiledAssembly) return null; var assemblyDefinition = Utils.LoadAssemblyDefinition(compiledAssembly); - var generator = new InjectionILGenerator(assemblyDefinition.MainModule, null); + var generator = new InjectionILGenerator(assemblyDefinition.MainModule, compiledAssembly, null); if (generator.TryGenerate(out var diagnosticMessages)) {