diff --git a/Samples/Directory.Build.targets b/Samples/Directory.Build.targets
index dd7fa89..ed1082d 100644
--- a/Samples/Directory.Build.targets
+++ b/Samples/Directory.Build.targets
@@ -64,6 +64,31 @@
+
+
+
+
+
+
+
+
+
+
@@ -84,6 +109,8 @@
+
+
\ No newline at end of file
diff --git a/src/RoslynCodeTaskFactory.UnitTests/CodeTaskFactoryTests.cs b/src/RoslynCodeTaskFactory.UnitTests/CodeTaskFactoryTests.cs
index f371815..29c824b 100644
--- a/src/RoslynCodeTaskFactory.UnitTests/CodeTaskFactoryTests.cs
+++ b/src/RoslynCodeTaskFactory.UnitTests/CodeTaskFactoryTests.cs
@@ -152,6 +152,21 @@ public void CodeLanguageFromTaskBody()
TryLoadTaskBodyAndExpectSuccess("code", expectedCodeLanguage: "VB");
}
+ [Test]
+ public void CodeTypeClassIgnoresParameterGroupWarning()
+ {
+ TryLoadTaskBodyAndExpectSuccess(
+ taskBody: "code",
+ parameters: new[]
+ {
+ new TaskPropertyInfo("P", typeof(string), false, false),
+ },
+ expectedWarningMessages: new[]
+ {
+ "Parameters are discovered through reflection for Type=\"Class\". Values specified in will be ignored.",
+ });
+ }
+
[Test]
public void CodeTypeFromTaskBody()
{
@@ -466,7 +481,8 @@ private void TryLoadTaskBodyAndExpectSuccess(
ISet expectedNamespaces = null,
string expectedCodeLanguage = null,
CodeTaskFactoryCodeType? expectedCodeType = null,
- string expectedSourceCode = null)
+ string expectedSourceCode = null,
+ IReadOnlyList expectedWarningMessages = null)
{
MockBuildEngine buildEngine = new MockBuildEngine();
@@ -478,6 +494,7 @@ private void TryLoadTaskBodyAndExpectSuccess(
bool success = CodeTaskFactory.TryLoadTaskBody(log, TaskName, taskBody, parameters ?? new List(), out TaskInfo taskInfo);
buildEngine.Errors.ShouldBe(new string[0]);
+ buildEngine.Warnings.ShouldBe(expectedWarningMessages ?? new string[0]);
Assert.True(success);
@@ -523,6 +540,8 @@ private sealed class MockBuildEngine : IBuildEngine
public string ProjectFileOfTaskNode { get; } = String.Empty;
+ public IEnumerable Warnings => Events.OfType().Select(i => i.Message);
+
public bool BuildProjectFile(string projectFileName, string[] targetNames, IDictionary globalProperties, IDictionary targetOutputs)
{
throw new NotSupportedException();
diff --git a/src/RoslynCodeTaskFactory/CodeTaskFactory.cs b/src/RoslynCodeTaskFactory/CodeTaskFactory.cs
index 499df24..76f6021 100644
--- a/src/RoslynCodeTaskFactory/CodeTaskFactory.cs
+++ b/src/RoslynCodeTaskFactory/CodeTaskFactory.cs
@@ -187,6 +187,28 @@ public bool Initialize(string taskName, IDictionary pa
TaskType = assembly.GetExportedTypes().FirstOrDefault(type => type.Name.Equals(taskName));
}
+ if (TaskType != null)
+ {
+ // Perform automatic parameter detection if the user supplied a class.
+ // This reduces the burden of the developer by not requiring them to
+ // manually specify .
+ //
+ if (taskInfo.CodeType == CodeTaskFactoryCodeType.Class)
+ {
+ PropertyInfo[] properties = TaskType.GetProperties(BindingFlags.Instance | BindingFlags.Public);
+ _parameters = new TaskPropertyInfo[properties.Length];
+ for (int i = 0; i < properties.Length; i++)
+ {
+ PropertyInfo property = properties[i];
+ _parameters[i] = new TaskPropertyInfo(
+ property.Name,
+ property.PropertyType,
+ property.GetCustomAttribute() != null,
+ property.GetCustomAttribute() != null);
+ }
+ }
+ }
+
AppDomain.CurrentDomain.AssemblyResolve += AppDomain_AssemblyResolve;
// Initialization succeeded if we found a type matching the task name from the compiled assembly
@@ -395,6 +417,13 @@ internal static bool TryLoadTaskBody(TaskLoggingHelper log, string taskName, str
taskInfo.CodeType = codeType;
}
+ // Warn that is ignored if any parameters are supplied when Type="Class".
+ //
+ if (taskInfo.CodeType == CodeTaskFactoryCodeType.Class && parameters.Any())
+ {
+ log.LogWarningWithCodeFromResources("CodeTaskFactory_ParameterGroupIgnoredForCodeTypeClass");
+ }
+
if (languageAttribute != null)
{
if (String.IsNullOrWhiteSpace(languageAttribute.Value))
diff --git a/src/RoslynCodeTaskFactory/Properties/Strings.Designer.cs b/src/RoslynCodeTaskFactory/Properties/Strings.Designer.cs
index 828f2a8..9675260 100644
--- a/src/RoslynCodeTaskFactory/Properties/Strings.Designer.cs
+++ b/src/RoslynCodeTaskFactory/Properties/Strings.Designer.cs
@@ -159,6 +159,15 @@ internal static string CodeTaskFactory_NoSourceCode {
}
}
+ ///
+ /// Looks up a localized string similar to Parameters are discovered through reflection for Type="Class". Values specified in will be ignored..
+ ///
+ internal static string CodeTaskFactory_ParameterGroupIgnoredForCodeTypeClass {
+ get {
+ return ResourceManager.GetString("CodeTaskFactory_ParameterGroupIgnoredForCodeTypeClass", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to Waiting for debugger to attach ({0} PID {1}). Press enter to continue....
///
diff --git a/src/RoslynCodeTaskFactory/Properties/Strings.resx b/src/RoslynCodeTaskFactory/Properties/Strings.resx
index f9e148b..2346bd6 100644
--- a/src/RoslynCodeTaskFactory/Properties/Strings.resx
+++ b/src/RoslynCodeTaskFactory/Properties/Strings.resx
@@ -159,6 +159,9 @@
MSB3428: You must specify source code within the Code element or a path to a file containing source code.
{StrBegin="MSB3428: "}
+
+ Parameters are discovered through reflection for Type="Class". Values specified in <ParameterGroup/> will be ignored.
+
Waiting for debugger to attach ({0} PID {1}). Press enter to continue...