활동 대리자 사용
작업 대리자를 사용하면 활동 작성자는 활동 사용자가 활동 기반 처리기를 제공할 수 있는 특정 시그니처가 있는 콜백을 노출할 수 있습니다. 두 가지 형식의 작업 대리자를 사용할 수 있습니다. ActivityAction<T>은 반환 값이 없는 작업 대리자를 정의하는 데 사용되고 ActivityFunc<TResult>은 반환 값이 있는 작업 대리자를 정의하는 데 사용됩니다.
작업 대리자는 자식 작업이 특정 서명을 갖도록 제한되어야 하는 시나리오에서 유용합니다. 예를 들어 While 활동은 제약 조건 없이 모든 형식의 자식 활동을 포함할 수 있지만 ForEach<T> 활동의 본문은 ActivityAction<T>이며 최종적으로 ForEach<T>에서 실행되는 자식 활동에는 InArgument<T>이 열거하는 컬렉션 멤버와 동일한 형식의 ForEach<T>이 있어야 합니다.
ActivityAction 사용
Catch 활동이나 ForEach<T> 활동 같은 여러 가지 .NET Framework 4.6.1 활동에 활동 동작이 사용됩니다. 각 경우에 활동 동작은 해당 활동 중 하나를 사용하여 워크플로를 작성할 때 필요한 동작을 제공하기 위해 워크플로 작성자가 활동을 지정하는 위치를 나타냅니다. 다음 예제에서는 ForEach<T> 활동을 사용하여 콘솔 창에 텍스트를 표시합니다. ForEach<T>의 본문은 문자열인 ActivityAction<T>의 형식에 일치하는 ForEach<T>을 사용하여 지정됩니다. WriteLine에 지정된 Handler 활동의 Text 인수는 ForEach<T> 활동의 반복 대상인 컬렉션의 문자열 값에 바인딩됩니다.
DelegateInArgument<string> actionArgument = new DelegateInArgument<string>();
Activity wf = new ForEach<string>
{
Body = new ActivityAction<string>
{
Argument = actionArgument,
Handler = new WriteLine
{
Text = new InArgument<string>(actionArgument)
}
}
};
List<string> items = new List<string>();
items.Add("Hello");
items.Add("World.");
Dictionary<string, object> inputs = new Dictionary<string, object>();
inputs.Add("Values", items);
WorkflowInvoker.Invoke(wf, inputs);
actionArgument는 컬렉션의 개별 항목을 WriteLine으로 이동하는 데 사용됩니다. 워크플로가 호출되면 다음 출력이 콘솔에 표시됩니다.
HelloWorld.
이 항목의 예에서는 개체 초기화 구문을 사용합니다. 개체 초기화 구문은 워크플로에 있는 활동의 계층적 뷰를 제공하고 활동 간의 관계를 표시하기 때문에 코드에서 워크플로 정의를 만드는 유용한 방법일 수 있습니다. 프로그래밍 방식으로 워크플로를 만들 때 개체 초기화 구문을 사용하기 위한 요구 사항은 없습니다. 다음 예는 이전 예와 기능적으로 동일합니다.
DelegateInArgument<string> actionArgument = new DelegateInArgument<string>();
WriteLine output = new WriteLine();
output.Text = new InArgument<string>(actionArgument);
ActivityAction<string> body = new ActivityAction<string>();
body.Argument = actionArgument;
body.Handler = output;
ForEach<string> wf = new ForEach<string>();
wf.Body = body;
List<string> items = new List<string>();
items.Add("Hello");
items.Add("World.");
Dictionary<string, object> inputs = new Dictionary<string, object>();
inputs.Add("Values", items);
WorkflowInvoker.Invoke(wf, inputs);
개체 이니셜라이저에 대한 자세한 내용은 방법: 생성자를 호출하지 않고 개체 초기화(C# 프로그래밍 가이드) 및 방법: 개체 이니셜라이저를 사용하여 개체 선언(Visual Basic)을 참조하세요.
다음 예제에서는 TryCatch 활동이 워크플로에 사용됩니다. ApplicationException이 워크플로를 통해 throw되고 Catch<TException> 활동을 통해 처리됩니다. Catch<TException> 활동의 활동 동작에 대한 처리기는 WriteLine 활동이며, 예외 세부 사항은 ex
DelegateInArgument<T>를 사용하여 처리기로 전달됩니다.
DelegateInArgument<ApplicationException> ex = new DelegateInArgument<ApplicationException>()
{
Name = "ex"
};
Activity wf = new TryCatch
{
Try = new Throw()
{
Exception = new InArgument<Exception>((env) => new ApplicationException("An ApplicationException was thrown."))
},
Catches =
{
new Catch<ApplicationException>
{
Action = new ActivityAction<ApplicationException>
{
Argument = ex,
Handler = new WriteLine()
{
Text = new InArgument<string>((env) => ex.Get(env).Message)
}
}
}
},
Finally = new WriteLine()
{
Text = "Executing in Finally."
}
};
ActivityAction<T>을 정의하는 사용자 지정 활동을 만들 때는 InvokeAction<T>을 사용하여 해당 ActivityAction<T>의 호출을 모델링합니다. 이 예제에서는 사용자 지정 WriteLineWithNotification
활동을 정의합니다. 이 활동은 Sequence 활동과, 문자열 인수 하나를 사용하는 WriteLine을 호출하는 InvokeAction<T>을 차례로 포함하는 ActivityAction<T>로 구성됩니다.
public class WriteLineWithNotification : Activity
{
public InArgument<string> Text { get; set; }
public ActivityAction<string> TextProcessedAction { get; set; }
public WriteLineWithNotification()
{
this.Implementation = () => new Sequence
{
Activities =
{
new WriteLine
{
Text = new InArgument<string>((env) => Text.Get(env))
},
new InvokeAction<string>
{
Action = TextProcessedAction,
Argument = new InArgument<string>((env) => Text.Get(env))
}
}
};
}
}
WriteLineWithNotification
활동을 사용하여 워크플로를 만드는 경우 워크플로 작성자는 필요한 사용자 지정 논리를 활동 동작의 Handler에 지정합니다. 이 예제에서는 WriteLineWithNotification
활동을 사용하는 워크플로를 만들고 WriteLine 활동을 Handler로 사용합니다.
// Create and invoke the workflow without specifying any activity action
// for TextProcessed.
Activity wf = new WriteLineWithNotification
{
Text = "Hello World."
};
WorkflowInvoker.Invoke(wf);
// Output:
// Hello World.
// Create and Invoke the workflow with specifying an activity action
// for TextProcessed.
DelegateInArgument<string> msg = new DelegateInArgument<string>();
Activity wf2 = new WriteLineWithNotification
{
Text = "Hello World with activity action.",
TextProcessedAction = new ActivityAction<string>
{
Argument = msg,
Handler = new WriteLine
{
Text = new InArgument<string>((env) => "Handler of: " + msg.Get(env))
}
}
};
// Invoke the workflow with an activity action specified
WorkflowInvoker.Invoke(wf2);
// Output:
// Hello World with activity action.
// Handler of: Hello World with activity action.
하나 이상의 인수를 전달하기 위해 제공된 일반 버전의 여러 InvokeAction<T> 및 ActivityAction<T>이 있습니다.
ActivityFunc 사용
ActivityAction<T>은 활동의 결과 값이 없는 경우에 유용하고, 결과 값이 반환되는 경우에는 ActivityFunc<TResult>이 사용됩니다. ActivityFunc<TResult>을 정의하는 사용자 지정 활동을 만들 때는 InvokeFunc<TResult>을 사용하여 해당 ActivityFunc<TResult>의 호출을 모델링합니다. 다음 예제에서는 WriteFillerText
활동을 정의합니다. 필터 텍스트를 제공하기 위해 정수 인수를 사용하고 문자열 결과를 반환하는 InvokeFunc<TResult>을 지정합니다. 필터 텍스트가 검색되면 WriteLine 활동을 사용하여 해당 텍스트가 콘솔에 표시됩니다.
public class WriteFillerText : Activity
{
public ActivityFunc<int, string> GetText { get; set; }
public InArgument<int> Quantity { get; set; }
Variable<string> text = new Variable<string>
{
Name = "Text"
};
public WriteFillerText()
{
this.Implementation = () => new Sequence
{
Variables =
{
text
},
Activities =
{
new InvokeFunc<int, string>
{
Func = GetText,
Argument = new InArgument<int>((env) => Quantity.Get(env)),
Result = new OutArgument<string>(text)
},
new WriteLine
{
Text = new InArgument<string>(text)
}
}
};
}
}
텍스트를 제공하기 위해 int
인수 하나를 사용하고 문자열 결과가 있는 활동을 사용해야 합니다. 이 예제에서는 이 요구 사항과 일치하는 TextGenerator
활동을 보여 줍니다.
public class TextGenerator : CodeActivity<string>
{
public InArgument<int> Quantity { get; set; }
public InArgument<string> Text { get; set; }
protected override string Execute(CodeActivityContext context)
{
// Provide a quantity of Random Text
int q = Quantity.Get(context);
if (q < 1)
{
q = 1;
}
string text = Text.Get(context) + " ";
StringBuilder sb = new StringBuilder(text.Length * q);
for (int i = 0; i < q; i++)
{
sb.Append(text);
}
return sb.ToString();
}
}
TextGenerator
활동을 WriteFillerText
활동과 함께 사용하려면 이 활동을 Handler로 지정합니다.
DelegateInArgument<int> actionArgument = new DelegateInArgument<int>();
Activity wf = new WriteFillerText
{
Quantity = 5,
GetText = new ActivityFunc<int, string>
{
Argument = actionArgument,
Handler = new TextGenerator
{
Quantity = new InArgument<int>(actionArgument),
Text = "Hello World."
}
}
};
WorkflowInvoker.Invoke(wf);
.NET