Design pattern for surrounding code in start, complete and fail methods - c#

Suppose I have various arbitrary sections of code to run, but before each section, I have to run a Start() method and then after each section I need to run a Complete() method. However, if an exception is thrown in the code section, I want to run a Fail(string message) method instead of Complete(). Is there a design pattern that elegantly encapsulates this to make it neat and easily repeatable?
For example, let's say I have a type called Thing that contains a Start() method that adds a row to a logging db table to reflect that a task is in progress, a Complete() method that changes that row to reflect that the task finished and a Fail(string message) method that changes the row to reflect that the task failed. These are just examples though, they could be doing any set-up and tidy up type tasks.
The naive implementation might be simply to call those methods manually:
public void DoStuff()
{
var thing = new Thing();
thing.Start();
try
{
DoImportantStuff();
thing.Complete();
}
catch (Exception e)
{
thing.Fail(e.Message);
}
}
But if I'm going to have to repeat this in a lot of different places, it ends up creating quite a lot of duplication and it might be easy to forget to call Complete or mess this up in some subtle way.
In C#, there's the using pattern, which provides a good way of encapsulating most of this. For example, if my Thing type looked like this:
public class Thing : IDisposable
{
public Thing(){
Start();
}
private void Start() { /* start */ }
private void Complete() { /* complete */ }
public void Dispose()
{
Complete();
}
}
My DoStuff() method could now be simplified to this:
public void DoStuff()
{
using(new Thing())
{
DoImportantStuff();
}
}
Which is much nicer. But it doesn't allow me to call Fail instead of Complete if an exception is thrown because (I think!) the Dispose method is essentially called in a Finally block.
I have thought of having a try/catch inside the using block and then setting a thing.HasFailed flag inside the catch block and then using that in the Dispose method to decide whether to Complete or Fail. But that seems a bit fiddly and I'd like the consumer of Thing to have to do as little as possible to make it work correctly.
So is there a design pattern that encapsulates what I want to do and avoids the need to manually write a try\catch each time?

You could have a Thing like this:
public class Thing
{
private void Start() { /* start */ }
private void Complete() { /* complete */ }
private void Fail(string message) {}
public void DoAction(Action action)
{
this.Start();
try
{
action();
this.Complete();
}
catch (Exception e)
{
this.Fail(e.Message);
}
}
}
And Use it like this:
Thing thing = new Thing();
thing.DoAction(this.DoStuff);

The pattern is called "template method". You can find your implementation under the title "aspect oriented programming".
(https://msdn.microsoft.com/en-us/library/aa288717(v=vs.71).aspx)

Using Delegates.
public class Thing : IDisposable
{
private void Start() { /* start */ }
private void Complete() { /* complete */ }
private void Fail(string _szMessage) {/* fail */}
public delegate void ProcessClientStuff();
private ProcessClientStuff m_delegateClientStuff;
public Thing(ProcessClientStuff _delegateClientStuff) {m_delegateClientStuff = _delegateClientStuff}
public void Dostuff()
{
Start();
try
{
m_delegateClientStuff();
Complete();
}
catch(Exception e)
{
Fail(e.Message);
}
}
}
void ClientStuff()
{
Console.WriteLine("Hello");
}
Thing oClientStuffProcessor = new Thing(ClientStuff);
oClientStuffProcessor.Dostuff();

Related

Conditional execution of methods based on some static boolean value

I want to do something like:
public void DoSomething()
{
if (!SomeStaticClass.CanDoWork)
{
return;
}
}
public void DoSomethingElse()
{
if (!SomeStaticClass.CanDoWork)
{
return;
}
// ....
}
I want to avoid duplication, since this would be present in a lot of class methods.
I tried looking into ConditionalAttribute but it seems that can't easily fix this issue.
Can this be done by Method attributes, or any other 'easy' way, if there isn't an 'easy' way, since the last approach would be to add an IF statement to every method.
with the context given by you, the first things that comes to my mind is to make a wrapping method that would contain the if statement. It would get the real method as parameter and excecute it condionally.
public class MyClass
{
public void DoSomething()
{
ConditionalExcecution(()=> DoSomethingOnlyCode());
}
private void DoSomethingOnlyCode()
{
// here the entire code
}
private void DoSomethingElseOnlyCode()
{
// here the entire code
}
public void DoSomethingElse()
{
ConditionalExcecution(()=> DoSomethingElseOnlyCode());
}
private void ConditionalExcecution(Action action)
{
if (SomeStaticClass.CanDoWork)
{
action();
}
}
}
This way you would have the if statement only in 1 place and hide the unconditional method code from the user of your API by private methods.
Depending on your context there might be better solutions to this dilema.

Wrapping a callback-based class to an async one

I'm referencing a class that performs various demanding operations using callbacks rather than async operations. For example:
class CallbackClass : SomeSdkCallbacks
{
public void RequestData()
{
// We call this to request some data.
// After some time, this will trigger OnDataReturned to be called
}
public void OnDataReturned(DataObject data)
{
// This will be called automatically with returned data via SomeSdkCallbacks
}
}
There are many instances of this type of structure throughout this class.
What I'm trying to do is create a wrapper class around this one that simplifies it's usage. The structure that I'm going for at the moment is:
class MyWrapperClass
{
CallbackClass CallbackClass;
public MyWrapperClass()
{
this.CallbackClass = new CallbackClass();
}
public DataObject GetData()
{
this.CallbackClass.RequestData();
// Somehow wait until this.CallbackClass.OnDataReturned is called?
// Somehow get the data that would be passed in to this.CallbackClass.OnDataReturned()???
}
}
What is the best method of wrapping up a 'callback' architecture into a single asynchronous method?
Edit: To clarify, ideally I would like to package this up into a single method that can return the data in a single request. See the MyWrapperClass.GetData() method in my example for my ideal structure.
Edit 2: I'm aware that this desired architecture is bad form. Unfortunately that is the requested structure that has been asked of me.
I think this is what you want:
class CallbackClass<T>
{
private TaskCompletionSource<T> task = new TaskCompletionSource<T>();
public void RequestData()
{
}
public void OnDataReturned(T data)
{
task.SetResult(data);
}
public Task<T> Task { get { return task.Task; } }
}
class MyWrapperClass
{
public Task<DataObject> GetData()
{
var cls = new CallbackClass<DataObject>();
cls.RequestData();
return cls.Task;
}
}
Just note that TaskCompletionSource must be created per operation so you don't use the same one for two different calls. With this you can use the async keyword. This might help a bit more.
In your situation you can add some event on CallBackClass.
Like here:
class CallbackClass : SomeSdkCallbacks
{
public event Action<object> DataReturnedEvent;
public void RequestData()
{
// We call this to request some data.
// After some time, this will trigger OnDataReturned to be called
}
public void OnDataReturned(DataObject data)
{
DataReturnedEvent?.Invoke(data);
}
}
And you can use the event in the wrapper class
class MyWrapperClass
{
CallbackClass CallbackClass;
public MyWrapperClass()
{
this.CallbackClass = new CallbackClass();
CallbackClass.DataReturnedEvent =+ ProcessData;
}
private void ProcessData(object Data)
{
//some data processing
}
public DataObject GetData()
{
this.CallbackClass.RequestData()
}
}

C# template method which changes logic at runtime

I am writing a method in c# class as shown below:
using(sftpClient)
{
sftpClient.Connect();
try{
//Do some process
}
catch(Exception ex)
{
}
sftpClient.Disconnect();
}
I need to create some more methods similar to the above but the logic changes only inside the try{} catch{} block. Can anyone suggest some best way to achieve this using some design pattern?
You could create an abstract base class:
abstract class MyBaseClass {
protected abstract void DoSomething();
public void DoSmtpStuff() {
smtpClient.Connect();
try {
DoSomething();
} catch (Exception ex) {
}
smtpClient.Disconnect();
}
}
and then just create inheritances of that class, which implement only the DoSomething method.
Take a look at the Strategy Pattern (emphasis my own):
In computer programming, the strategy pattern (also known as the
policy pattern) is a software design pattern that enables an
algorithm's behavior to be selected at runtime.
So basically, you would declare an interface, say, IBehaviour and define some method:
public interface IBehaviour
{
void Process();
}
Then have a different class implement IBehaviour for each piece of logic you want to have.
The class where you need to consume the logic would then allow passing an IBehaviour object and in your try block just do behaviour.Process().
This will allow you to set up the behaviour from outside the class and then simply pass it along to the class in which you want to actually do something with it.
Alternative to classes is just take Action as argument:
TResult WithSftpClient<TResult>(Func<TResult, SftpClient> operation)
{
TResult result = default(TResult);
// Note that one may need to re-create "client" here
// as it is disposed on every WithSftpClient call -
// make sure it is re-initialized in some way.
using(sftpClient)
{
sftpClient.Connect();
try
{
result = operation(sftpClient);
}
catch(Exception ex)
{
// log/retrhow exception as appropriate
}
// hack if given class does not close connection on Dispose
// for properly designed IDisposable class similar line not needed
sftpClient.Disconnect();
}
return result;
}
And use it:
var file = WithSftpClient(client => client.GetSomeFile("file.name"));
You can use this pattern:
abstract class ProcedureBase<T>
{
public T Work()
{
using(sftpClient)
{
sftpClient.Connect();
try{
ProtectedWork();
}
catch(Exception ex)
{
}
sftpClient.Disconnect();
}
}
protected abstract T ProtectedWork();
}
class Procedure1 : ProcedureBase<TypeToReturn>
{
protected override TypeToReturn ProtectedWork()
{
//Do something
}
}
class Procedure2 : ProcedureBase<AnotherTypeToReturn>
{
protected override AnotherTypeToReturn ProtectedWork()
{
//Do something
}
}
Usage:
static void Main(string[] args)
{
Procedure1 proc = new Procedure1();
proc.Work();
}

Is there a way to avoid method calling repetition?

I am building a game where several methods are chained to other and need to called behind the scenes. For example, when a soldier needs to leave the castle, the gate needs to be opened and then closed as soon as he leaves:
public void MoveTheGate(bool openTheGate)
{
if (openTheGate)
{
// code for: open the gate
}
else
{
// code for: close the gate
}
}
public void GetOutOfTheCastle()
{
MoveTheGate(true);
// code for: get out of the castle
MoveTheGate(false);
}
The same is true for when a messenger from another kingdom reaches the castle, the MoveTheGate() method has to be called both in the beginning and in the end of the messenger's entrance to the castle.
Is there a more delicate way to achieve this?
you could do
OpenGate(()=>
{ stuff to do with gate open }
);
where OpenGate is
public void OpenGate(Action action)
{
try
{
MoveTheGate(true);
action();
}
finally
{
MoveTheGate(false);
}
}
This may be total overkill, but you could always implement IDisposable then use a using block. That's a nice way to "make sure" it happens.
If you set up a class that called some given action on dispose,
public class DelegateDisposable : IDisposable
{
private readonly Action action;
public DelegateDisposable(Action action)
{
this.action = action;
}
public void Dispose()
{
if(this.action != null)
{
this.action();
}
}
}
Then you could use it like this:
private IDisposable OpenGate()
{
MoveTheGate(true);
return new DelegateDisposable(() => MoveTheGate(false));
}
And use it like this:
public void GetOutOfTheCastle()
{
using (OpenGate())
{
// code for: get out of the castle
}
}
A nice advantage of this approach is that it doesn't mess with your callstack, although again, it does have some overhead. But if you brought DelegateDisposable into some utility class, it could probably be useful for something else as well.
I would be impartial to an inheritance pattern that forces you to perform actions within the context of a base, inherited abstract class. The reason I believe this is preferable is because it allows you to easily encapsulate your Gate opening and closing and does not expose either the conditions for that to occur or that functionality outside of an inherited scenario.
public void Main()
{
var x = new InheritedAction();
}
public abstract class BaseGateAction
{
public void PerformBaseAction(Action actionToPerformWhileGateIsOpen)
{
Open();
actionToPerformWhileGateIsOpen();
Close();
}
private void Open()
{
Console.WriteLine("Gate has been opened");
}
private void Close()
{
Console.WriteLine("Gate has been closed");
}
}
public class InheritedAction : BaseGateAction
{
public InheritedAction()
{
PerformBaseAction(() =>
Console.WriteLine("Attack the dragon while the gate is open"));
PerformBaseAction(() =>
{
Console.WriteLine("Attack the dragon while the gate is open");
Console.WriteLine("The dragon is victorious and you have been devoured");
});
}
}
This code sample outputs the following for both PerformBaseAction method calls respectively:
Gate has been opened
Attack the dragon while the gate is open
Gate has been closed
Gate has been opened
Attack the dragon while the gate is open
The dragon is victorious and you have been devoured
Gate has been closed
This would allow for not only better code reuse, but far more encapsulated logic. You could always add additional exposed methods that take pre-conditions or post-conditions that would affect whether or not you could open the gate.
public abstract class BaseGateAction
{
....
public void PerformBaseActionWithPrecondition(Func<bool> precondition, Action actionToPerformWhileGateIsOpen)
{
if (precondition())
{
PerformBaseAction(actionToPerformWhileGateIsOpen);
}
else
{
Console.WriteLine("The gate could not be opened!");
}
}
...
}
This could be called as follows:
PerformBaseActionWithPrecondition<bool>(
() => true == false,
() => Console.WriteLine("Attack!")
);
And would output:
The gate could not be opened!

How to convert an exception to another one using PostSharp?

I would like to automagically add the following code around the body of some methods:
try
{
// method body
}
catch (Exception e)
{
throw new MyException("Some appropriate message", e);
}
I am working with PostSharp 1.0 and this is what I've done at the moment:
public override void OnException(MethodExecutionEventArgs eventArgs)
{
throw new MyException("Some appropriate message", eventArgs.Exception);
}
My problem is that I can see the PostSharp OnException call in the stack.
What would be the good practice to avoid this and get the same call stack as implementing by hand the exception handler?
There is no way to hide "OnException" from the call stack.
Two things working in tandem will allow you to do this:
The fact that Exception.StackTrace is virtual
The use of the skipFrames parameter to the StackFrame constructor. This is not required, but makes things easier
The below example demonstrates how to customize the stack trace. Note that I know of no way to customize the Exception.TargetSite property, which still gives the details of the method from which the exception originated.
using System;
using System.Diagnostics;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
// exception is reported at method A, even though it is thrown by method B
MethodA();
}
private static void MethodA()
{
MethodB();
}
private static void MethodB()
{
throw new MyException();
}
}
public class MyException : Exception
{
private readonly string _stackTrace;
public MyException()
{
// skip the top two frames, which would be this constructor and whoever called us
_stackTrace = new StackTrace(2).ToString();
}
public override string StackTrace
{
get { return _stackTrace; }
}
}
}

Categories

Resources