diff --git a/dotnet/src/Microsoft.Agents.AI.Workflows/WorkflowBuilderExtensions.cs b/dotnet/src/Microsoft.Agents.AI.Workflows/WorkflowBuilderExtensions.cs index f9c3e2056a..b09dec91f4 100644 --- a/dotnet/src/Microsoft.Agents.AI.Workflows/WorkflowBuilderExtensions.cs +++ b/dotnet/src/Microsoft.Agents.AI.Workflows/WorkflowBuilderExtensions.cs @@ -25,7 +25,11 @@ public static class WorkflowBuilderExtensions /// The target executor to which messages will be forwarded. /// The updated instance. public static WorkflowBuilder ForwardMessage(this WorkflowBuilder builder, ExecutorBinding source, ExecutorBinding target) - => builder.ForwardMessage(source, [target], condition: null); + { + Throw.IfNull(target); + + return builder.ForwardMessage(source, [target], condition: null); + } /// /// Adds edges to the workflow that forward messages of the specified type from the source executor to @@ -57,17 +61,14 @@ public static class WorkflowBuilderExtensions Throw.IfNull(targets); Func predicate = WorkflowBuilder.CreateConditionFunc(IsAllowedTypeAndMatchingCondition)!; + List targetList = targets.Select(target => Throw.IfNull(target, nameof(targets))).ToList(); -#if NET - if (targets.TryGetNonEnumeratedCount(out int count) && count == 1) -#else - if (targets is ICollection { Count: 1 }) -#endif + if (targetList.Count == 1) { - return builder.AddEdge(source, targets.First(), predicate); + return builder.AddEdge(source, targetList[0], predicate); } - return builder.AddSwitch(source, (switch_) => switch_.AddCase(predicate, targets)); + return builder.AddSwitch(source, (switch_) => switch_.AddCase(predicate, targetList)); // The reason we can check for "not null" here is that CreateConditionFunc will do the correct unwrapping // logic for PortableValues. @@ -83,7 +84,11 @@ public static class WorkflowBuilderExtensions /// The target executor to which messages, except those of type , will be forwarded. /// The updated instance with the added edges. public static WorkflowBuilder ForwardExcept(this WorkflowBuilder builder, ExecutorBinding source, ExecutorBinding target) - => builder.ForwardExcept(source, [target]); + { + Throw.IfNull(target); + + return builder.ForwardExcept(source, [target]); + } /// /// Adds edges from the specified source to the provided executors, excluding messages of a specified type. @@ -100,17 +105,14 @@ public static class WorkflowBuilderExtensions Throw.IfNull(targets); Func predicate = WorkflowBuilder.CreateConditionFunc((Func)IsAllowedType)!; + List targetList = targets.Select(target => Throw.IfNull(target, nameof(targets))).ToList(); -#if NET - if (targets.TryGetNonEnumeratedCount(out int count) && count == 1) -#else - if (targets is ICollection { Count: 1 }) -#endif + if (targetList.Count == 1) { - return builder.AddEdge(source, targets.First(), predicate); + return builder.AddEdge(source, targetList[0], predicate); } - return builder.AddSwitch(source, (switch_) => switch_.AddCase(predicate, targets)); + return builder.AddSwitch(source, (switch_) => switch_.AddCase(predicate, targetList)); // The reason we can check for "null" here is that CreateConditionFunc will do the correct unwrapping // logic for PortableValues. diff --git a/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/WorkflowBuilderSmokeTests.cs b/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/WorkflowBuilderSmokeTests.cs index 1ca2027446..a44bd9ad8b 100644 --- a/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/WorkflowBuilderSmokeTests.cs +++ b/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/WorkflowBuilderSmokeTests.cs @@ -368,7 +368,7 @@ public partial class WorkflowBuilderSmokeTests Assert.Throws("source", () => builder.ForwardMessage(null!, target)); Assert.Throws("target", () => builder.ForwardMessage(source, (ExecutorBinding)null!)); Assert.Throws("targets", () => builder.ForwardMessage(source, (IEnumerable)null!)); - Assert.Throws("executors", () => builder.ForwardMessage(source, [target, null!])); + Assert.Throws("targets", () => builder.ForwardMessage(source, [target, null!])); Assert.Throws("targets", () => builder.ForwardMessage(source, [])); } @@ -385,7 +385,7 @@ public partial class WorkflowBuilderSmokeTests Assert.Throws("source", () => builder.ForwardExcept(null!, target)); Assert.Throws("target", () => builder.ForwardExcept(source, (ExecutorBinding)null!)); Assert.Throws("targets", () => builder.ForwardExcept(source, (IEnumerable)null!)); - Assert.Throws("executors", () => builder.ForwardExcept(source, [target, null!])); + Assert.Throws("targets", () => builder.ForwardExcept(source, [target, null!])); Assert.Throws("targets", () => builder.ForwardExcept(source, [])); }