can't use enum parameter type from arbitrary assembly
I have a custom msbuild task that specifies a public parameter of an enum type (CompressionLevel). msbuild rejects the parameter, even though the assembly reference is listed.
D:\CustomTasks.proj(52,25): error MSB4022: The result "System.IO.Compression.CompressionLevel" of evaluating the value "System.IO.Compression.CompressionLevel" of the "ParameterType" attribute in element <Parameter> is not valid.
<UsingTask TaskName="ZipDirectory" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
<ParameterGroup>
<Directory ParameterType="System.String" Required="True"/>
<DestinationZipFile ParameterType="System.String" Required="True"/>
<CompressionLevel ParameterType="System.IO.Compression.CompressionLevel" />
</ParameterGroup>
<Task>
<Reference Include="System.IO.Compression.FileSystem"/>
<Code Source="$(BuildScriptsDirectory)\ZipDirectory.cs"/>
</Task>
</UsingTask>
The root cause of this is how MSBuild resolves types in a UsingTaskParameterGroupElement, in ParseUsingTaskParameterGroupElement. That code calls Type.GetType and, if that fails, falls back to looking "next to ITaskItem". That's not sufficient in this case.
Without looking too deeply, I think that this can be improved by ensuring that all <Reference> tags have been considered before trying to figure out types for parameters. That would be a fairly large shift since we currently consider XML elements as they come, but it seems doable.
For now, there are workaround options:
- Accept a parameter of type
System.Stringand do type coercion in your code (this is my favorite, thanks for suggesting it @Craig-Campbell-MS). - Use a precompiled DLL for the task (possibly distributed via NuGet).