In Unity / .NET 4, ClassTypeReferencePropertyDrawer does not see app-defined classes.

Issue #3 new
Ed Halley created an issue
            var assembly = Assembly.GetExecutingAssembly();
            FilterTypes(assembly, filter, excludedTypes, types);

            foreach (var domainAssembly in AppDomain.CurrentDomain.GetAssemblies())
                FilterTypes(domainAssembly, filter, excludedTypes, types);

            foreach (var referencedAssembly in assembly.GetReferencedAssemblies())
                FilterTypes(Assembly.Load(referencedAssembly), filter, excludedTypes, types);

In ClassTypeReferencePropertyDrawer.cs, I added the above lines 3~5 (your lines 65~67) to allow the use of classes which are defined in the application domain but not in any loaded assemblies. Typical projects do not use assemblies for project-specific code until it is quite mature. For example, your own game may want to filter types based on game-related classes.

Comments (3)

  1. Chris Yarbrough

    I also changed this for my use case. I believe it’s more universal to simply iterate all loaded assemblies or make this configurable as a setting. For example, in my project, ClassTypeReference is part of the Plugins folder with its own ASMDEF. This assembly does not reference any other assemblies, instead, it is being referenced by the main application code. So the only way to get all types is by starting at the current app domain and iterating all of the assemblies.

  2. Artem Perepelitsa

    Yes, it’s one of the main issues with the code. As soon as ClassTypeReference is moved to a separate assembly, Assembly.GetExecutingAssembly() stops making sense. I reworked this completely, checking referenced assemblies of the declaring type instead, like this:

    var typeRelatedAssemblies = TypeCollector.GetAssembliesTypeHasAccessTo(_declaringType);
    
    // Somewhere in the TypeCollector class
    public static Assembly[] GetAssembliesTypeHasAccessTo(Type type)
    {
        Assembly typeAssembly;
    
        try
        {
            typeAssembly = type == null ? Assembly.Load("Assembly-CSharp") : type.Assembly;
        }
        catch (FileNotFoundException)
        {
            throw new FileNotFoundException("Assembly-CSharp.dll was not found. Please create any " +
                                            "script in the Assets folder so that the assembly is generated.");
        }
    
        return typeAssembly.GetReferencedAssemblies()
            .Select(Assembly.Load)
            .Append(typeAssembly)
            .ToArray();
    }
    

    You can get declaringType from the PropertyDrawer.fieldInfo property.

    I also added an IncludeAdditionalAssemblies attribute option if the referenced assemblies are not enough. You can check it out here.

  3. Log in to comment