I'm building a small reusable library for two systems our company manages.
Something that I've been caught up on is whether I should expose a set of properties of type Action<T>
for events such as Completed, Aborted, ExceptionOccured, or if I should use the Event<T>
T : EventArgs methodology.
In practice another internal library will be consuming this information and handling the display of information to the user. The library's classes will be instantiated within a single thread and wouldn't be consumed by anything outside of its owner.
To me it seems more along the lines of if I only need to notifications are only ever going to be consumed by one object then it doesn't matter, however for completeness, and due to the fact that I as the library auther have little control over how another developer implements this, I should use the Event method due to it's broader ability to handle events.
EDIT (sample code):
@Robert Harvey, I read that post when searching for reasoning on picking one over the other. I understand the answer in context to that question, but I'm not sure how it relates to using the event keyword or the simple assigning of a property.
@Fabio Marcolini, I understand that I'm using the word event to describe what is happening. What I'm trying to answer is that if using the event structure is preferred to simply executing a delegate property.
Here are the properties that I use to define the event actions:
public Action<WorkflowInstallerCompletedEventArgs> InstallCompleted;
public Action<System.Activities.Activity, WorkflowInstallerActivityCompletedEventArgs> ActivityCompleted;
public Action<System.Activities.Activity, WorkflowApplicationAbortedEventArgs> InstallAborted;
public Func<System.Activities.Activity, WorkflowApplicationUnhandledExceptionEventArgs, UnhandledExceptionAction> UnhandledExceptionDuringInstall;
The idea would be to invoke one of them in this manner:
if (this.InstallCompleted != null)
this.InstallCompleted(new WorkflowInstallerCompletedEventArgs(logs));
Now until @svick's comment I would've said that you could only have one Action (or Func) assigned to each property.
Example implementation:
WorkflowInstaller installer = new WorkflowInstaller(activity, new TestVariablesCollection()) { ActivitiesRunSequentially = true };
installer.AddInstallActivity(activity2);
installer.InstallCompleted = (e) =>
{
Log[] logs = e.Logs.ToArray();
string test = SerializationHelper<Log>.Serialize(logs.FirstOrDefault());
try
{
logOutputFromRun = SerializationHelper<Log[]>.Serialize(logs);
}
catch (Exception ex)
{
}
syncEvent.Set();
};
installer.InstallAborted = (a, e) =>
{
Assert.Fail("Unexpected abort during the install.");
syncEvent.Set();
};
installer.UnhandledExceptionDuringInstall = (a, e) =>
{
Assert.Fail("Unexpected exception during the install.");
syncEvent.Set();
return System.Activities.UnhandledExceptionAction.Terminate;
};
installer.StartInstallation();
syncEvent.WaitOne();
The answer to my question may not be a definitive this way or that way, but more of best practice or generally accepted approach. I'm really trying to expand my horizons when it comes to creating code that is acceptable to a wider audience.
Action<T>
doesn't return anything.Action<T>
is a single delegate. If you will only ever have one subscriber, anAction<T>
may be preferable, especially if it's never visible externally. Otherwise,event
s are a much better choice.Action a1 = …; Action a2 = …; Action combined = a1 + a2;
.