2014-11-21 5 views
1

나는 WF4 활동을 구현했다. 필요한 일부 InArguments, 하나는 InOutArgument가 필요하고 다른 하나는 OutArgument입니다.RequiredArgumentAttribute가 InOutArguments에서 올바르게 작동하지 않습니까?

활동이 xaml (즉, 워크 플로우 디자이너)에서 구현 되었기 때문에 xaml에서 analog를 '필수'로 표시하는 방법 (C에서 # [RequiredArgument]으로 변환)을 수행하는 방법에 대한 정보를 검색해야했습니다. 그것은 :

http://msdn.microsoft.com/en-us/library/ee358733(v=vs.100).aspx

<x:Property Name="Operand1" Type="InArgument(x:Int32)"> 
    <x:Property.Attributes> 
    <RequiredArgumentAttribute /> 
    </x:Property.Attributes> 
</x:Property> 

이 모든 InArguments을 위해 잘 작동합니다. 하지만 테스트를 구현할 때 InOutArguments에서 제대로 작동하지 않는다는 것을 알았습니다. 매개 변수를 제공하지 않고 내 테스트에서 WorkflowInvoker.Invoke으로 xaml 활동을 실행하면 이 필요한 모든 InArguments에 대해 불만을 제기하지만 필요한 InOutArgument는 불평하지 않습니다. 필요한 모든 InArguments를 사용하여 작업을 실행했지만 필요한 InOutArgument가없는 경우 아무런 ArgumentException도 throw되지 않습니다.

Workflow Foundation의 버그 일 수 있습니까?

재미있는 점은 매개 변수를 제공하지 않고 워크 플로에서이 활동을 사용하면 워크 플로 디자이너에서이 빨간색 느낌표가 표시되어 어떤 매개 변수에 입력이 필요한지 알 수 있다는 것입니다. 그리고 여기서 InOutArgument 은 언급 된 동작 인입니다.

답변

1

워크 플로 엔진은 RequiredArgumentAttribute를 검사하여 다른 작업을 호출하는 하나의 작업을 확인합니다. CodeActivity를 생성하면이를 실제로 볼 수 있습니다. 중단 점을 사용하면 CacheMetadata 메서드에서 디버거 중지를 볼 수 있지만 Execute 메서드가 호출되기 전에 예외가 throw됩니다.

그러나 WorkflowInvoker를 사용하여 InOut/Out 인수가있는 활동을 직접 호출해도 InOut/Out 필수 인수에 대한 예외는 발생하지 않습니다. RequiredArgumentAttribute에는 인수에 바인딩이 있어야합니다. 인수에 값이 필요하지 않습니다. 이것은 참조 변수를 널값으로 바인드하여 볼 수 있습니다. WorkflowInvoker 클래스는 반환되는 IDictionary 객체의 출력 값을 캡처하기 위해 InOut/Out 인수에 자동으로 바인딩합니다.

필수 InOut 인수에 대한 단위 테스트를 작성하려면 테스트중인 활동에 자신을 바인딩하는 활동을 만들어야합니다. 다음 스 니펫은이 정확한 시나리오에 대해 최근에 작성한 코드입니다. WorkflowInvoker를 캡슐화하기 위해 CodePlex의 WorkflowInvokerTest 클래스를 사용하고 있습니다.

[TestClass] 
public class WageTest : ActivityTest 
{ 
    [TestInitialize] 
    public void InitializeTest() 
    { 
     host = new WorkflowInvokerTest(new WageActivity()); 
     host.InArguments.Wage = 2000; 
     host.InArguments.IsFifthQuarter = false; 
    } 

    [TestMethod] 
    public void WageArgumentIsRequired() 
    { 
     base.TestForRequiredArgument("Wage"); 
    } 

    [TestMethod] 
    public void IsFifthQuarterArgumentIsRequired() 
    { 
     base.TestForRequiredArgument("IsFifthQuarter"); 
    } 

    //... 
} 

그것은 제네릭 조금 정리 될 수있다 :

public abstract class ActivityTest 
{ 
    private class ArgumentTester : NativeActivity 
    { 
     public Collection<Variable> variables = new Collection<Variable>(); 
     public Activity Test; 

     protected override void CacheMetadata(NativeActivityMetadata metadata) 
     { 
      base.CacheMetadata(metadata); 
      metadata.AddImplementationChild(Test); 
      foreach (var item in variables) 
      { 
       metadata.AddImplementationVariable(item); 
      } 
     } 

     protected override void Execute(NativeActivityContext context) 
     { 
      context.ScheduleActivity(Test); 
     } 
    } 

    protected WorkflowInvokerTest host; 

    protected void TestForRequiredArgument(string argName) 
    { 
     var d = (IDictionary<string, object>)host.InArguments; 
     d.Remove(argName); 

     try 
     { 
      dynamic activityToTest = System.Activator.CreateInstance(host.Activity.GetType()); 

      ArgumentTester tester = new ArgumentTester 
      { 
       Test = activityToTest 
      }; 

      foreach (var item in d) 
      { 
       Type t = typeof(Variable<>).MakeGenericType(item.Value.GetType()); 
       Variable v = (Variable)Activator.CreateInstance(t, item.Key + "_Var", item.Value); 
       tester.variables.Add(v); 
       var prop = host.Activity.GetType().GetProperty(item.Key); 
       object arg = Activator.CreateInstance(prop.PropertyType, v); 
       prop.SetValue(activityToTest, arg); 
      } 

      var h = new WorkflowInvokerTest(tester); 
      h.TestActivity(); 

      Assert.Fail("An exception should have been thrown."); 
     } 
     catch (InvalidWorkflowException ex) 
     { 
      Assert.IsTrue(ex.Message.Contains("'" + argName + "'")); 
     } 
     finally 
     { 
      host.Tracking.Trace(); 
     } 
    } 
} 

그리고는이 같은 테스트를 작성. 나는 아직도 그 일을하고 있지만 아이디어를 얻는다.

+0

이것은 매우 좋게 보입니다. 제네릭으로 정리 된 버전을 가지고 있다면, 나는 흥미가있을 것이다 ;-) – MaDev