How can I stop a method's execution using PostSharp? - c#

Currently I am trying to develop a solution that will check if a method has been executed and if some time has passed since it was last executed, given that it was and the time has passed, I would like to skip from the OnEntry method to the OnExit without actually executing any code from the method itself.
Sort of :
public class CacheThisMethod : OnMethodBoundaryAspect
{
public override void OnEntry(MethodExecutionArgs args)
{
if (isCached( args.Method.name)
{
args.MethodExecutionTag = getReturnValue(args.Method.name)
//jump to OnExit
}
else
{
//continue
}
}
public override void OnExit(MethodExecutionArgs args)
{
args.Method.ReturnValue = args.MethodExecutionTag;
}
}
How can I achieve this? Thanks.

The following modifications to your code show how to get what you want.
public class CacheThisMethod : OnMethodBoundaryAspect
{
public override void OnEntry(MethodExecutionArgs args)
{
if (isCached( args.Method.name)
{
args.MethodExecutionTag = getReturnValue(args.Method.name)
OnExit(args);
}
else
{
//continue
}
}
public override void OnExit(MethodExecutionArgs args)
{
//args.Method.ReturnValue = args.MethodExecutionTag;
args.ReturnValue = args.MethodExecutionTag;
args.FlowBehavior = FlowBehavior.Return;
}
}
However, if you are working on a per method name key, then you can use a simple property for your cached return value, as a separate instance of each aspect will be created for you when you attach your advice to a method.
If there is no reason to jump to the OnExit then just add the FlowBehaviour and return value setting to the OnEntry method at the point it makes the call to the OnExit method.

Related

Call multiple methods in a defined order

Picture a case like this:
I have a controller action (or service method) where I need to call three methods in a consecutive order, each method has a single responsibility.
public return_type MyMethod(_params_) {
// .. some code
Method_1 (...);
Method_2 (...);
Method_3 (...);
// ... some more code
}
A developer can make the mistake of calling Method_2 before Method_1, or at least we can say that nothing forces him to follow this order, or to get an exception when the order isn't followed.
Now we can call Method_2 inside Method_1, and Method_3 inside Method_2, but that doesn't seem right when each method handles a completely different responsibility.
Is there a design pattern for this situation? Or any "clean" way to handle this?
This is exactly what facade pattern do.
Try to extract the three methods to another class, and make them private. Expose a single method MyMethod that calls the other methods in the desired order. Clients should use Facade.MyMethod
More details: https://en.m.wikipedia.org/wiki/Facade_pattern
I suppose you should leave control of execution for yourself and give possibility just to set what should be executed.
public interface IMethodsExecutor
{
void Execute();
void ShouldRunMethod1();
void ShouldRunMethod2();
void ShouldRunMethod3();
}
public class MethodsExecutor: IMethodsExecutor
{
private bool _runMethod1;
private bool _runMethod2;
private bool _runMethod3;
public MethodsExecutor()
{
_runMethod1 = false;
_runMethod2 = false;
_runMethod3 = false;
}
public void ShouldRunMethod1()
{
_runMethod1 = true;
}
public void ShouldRunMethod2()
{
_runMethod2 = true;
}
public void ShouldRunMethod3()
{
_runMethod3 = true;
}
private void Method1()
{
}
private void Method2()
{
}
private void Method3()
{
}
public void Execute()
{
if (_runMethod1)
{
Method1();
}
if (_runMethod2)
{
Method2();
}
if (_runMethod3)
{
Method3();
}
}
}
So that the usage will be:
IMethodsExecutor methodsExecutor = new MethodsExecutor();
methodsExecutor.ShouldRunMethod1();
methodsExecutor.ShouldRunMethod3();
methodsExecutor.Execute();

Why is my interface method call ignored in a C# generic?

I am quite new to C# and I cannot understand the behaviour of a class in my project.
I am using an interface that defines a generic with a type constraint which is another interface.
When I call the generic, I know that a certain method exists on the argument (because of the type constraint), but this method doesn't get executed when I call it.
The only workaround I have so far is to include the method call into the type-specific method overloads.
This may be better explained with the following snippet with an equivalent type structure:
public interface ITrickable
{
void GetRabbitOut();
}
public interface IMagic
{
void DoTricks<T>(T obj) where T : ITrickable;
}
public class Hat : ITrickable
{
public void LiftUp() { Console.WriteLine("Lifting up the hat..."); }
public void GetRabbitOut() { Console.WriteLine("A rabbit came out the hat !"); }
}
public class Box : ITrickable
{
public void OpenDoubleBottom() { Console.WriteLine("Opening the box..."); }
public void GetRabbitOut() { Console.WriteLine("A rabbit came out the box !"); }
}
public abstract class Magician : IMagic
{
public abstract void DoTricks<T>(T obj) where T : ITrickable;
}
Now if I call DoTricks(new Hat()); DoTricks(new Box()); with the class below:
public class Houdini : Magician
{
public override void DoTricks<T>(T obj)
{
try {
DoTricks(obj); }
catch {
throw new NotImplementedException(); }
}
public void DoTricks(Hat obj)
{
obj.LiftUp();
obj.GetRabbitOut();
}
public void DoTricks(Box obj)
{
obj.OpenDoubleBottom();
obj.GetRabbitOut();
}
}
The output is as expected:
Lifting up the hat...
A rabbit came out the hat !
Opening the box...
A rabbit came out the box !
But if the class is defined as this one below:
public class Genesta : Magician
{
public override void DoTricks<T>(T obj)
{
try {
DoTricks(obj);
obj.GetRabbitOut(); } // <--- This seems to be ignored !?
catch {
throw new NotImplementedException(); }
}
public void DoTricks(Hat obj)
{
obj.LiftUp();
}
public void DoTricks(Box obj)
{
obj.OpenDoubleBottom();
}
}
The output is
Lifting up the hat...
Opening the box...
The question is why does GetRabbitOut is not called in the second class?
EDIT: The calling code is:
public static void Main(string[] args)
{
var houdini = new Houdini();
var hat = new Hat();
var box = new Box();
houdini.DoTricks(hat);
houdini.DoTricks(box);
Console.ReadLine();
}
Notice your method calls (I imagine it looked something resembling this):
Genesta g = new Genesta();
g.DoTricks(new Hat());
g.DoTricks(new Box());
Since you call g.DoTricks(new Hat()) rather than g.DoTricks<Hat>(new Hat()), no surprises that the exact method of the Genesta class that is invoked is DoTricks(T obj) and not DoTricks<T>(T obj). And when considering the implementation of DoTricks(T obj)...
public void DoTricks(Hat obj)
{
obj.LiftUp();
}
public void DoTricks(Box obj)
{
obj.OpenDoubleBottom();
}
The result is actually what you can expect from these methods!
If, however, you would call the generic method like this...
g.DoTricks<Hat>(new Hat());
You would fall into an infinite recursion, as the method would call itself indefinitely. DoTricks<T>(T obj) will always call itself and not one of the specialized overloads DoTricks(Hat) or DoTricks(Box), since the compiler cannot know before runtime that T will in fact be either Hat or Box.
By the way, the Houdini class experiences the same effect - it just so happens that its specific DoTricks(Hat) and DoTricks(Box) methods produce the result that you expected from calling DoTricks<T>(T obj).

Force code to execute in order?

I am seeing a strange problem in my C# code. I have something like this:
public static class ErrorHandler {
public static int ErrorIgnoreCount = 0;
public static void IncrementIgnoreCount() {
ErrorIgnoreCount++;
}
public static void DecrementIgnoreCount() {
ErrorIgnoreCount--;
}
public static void DoHandleError() {
// actual error handling code here
}
public static void HandleError() {
if (ErrorIgnoreCount == 0) {
DoHandleError();
}
}
}
public class SomeClass {
public void DoSomething() {
ErrorHandler.IncrementIgnoreCount();
CodeThatIsSupposedToGenerateErrors(); // some method; not shown
ErrorHandler.DecrementIgnoreCount();
}
}
The problem is that the compiler often decides that the order of the three calls in the DoSomething() method is not important. For example, the decrement may happen before the increment. The result is that when the code that is supposed to generate errors is run, the error handling code fires, which I don't want.
How can I prevent that?
Add Trace or Logs to your code in IncrementIgnoreCount, DecrementIgnoreCount and HandleError function.
That will help you to view real call order.

Execute Method Before and After Code Block

How could I wrap some code in brackets to do the following?
MyCustomStatement(args){
// code goes here
}
So that before the code in the brackets executes, it'll call a method and when the code in the brackets finishes executing it will call another method. Is there such a thing? I know it seems redundant to do this when I can simply call the methods before and after the code and all, but I simply was curious. I don't know how to word this exactly because I'm new to programming.
Thanks!
You can do this by storing the code in an abstract class that executes the "before" and "after" code for you when you call Run():
public abstract class Job
{
protected virtual void Before()
{
// Executed before Run()
}
// Implement to execute code
protected abstract void OnRun();
public void Run()
{
Before();
OnRun();
After();
}
protected virtual void After()
{
// Executed after Run()
}
}
public class CustomJob : Job
{
protected override void OnRun()
{
// Your code
}
}
And in the calling code:
new CustomJob().Run();
Of course then for every piece of custom code you'll have to create a new class, which may be less than desirable.
An easier way would be to use an Action:
public class BeforeAndAfterRunner
{
protected virtual void Before()
{
// Executed before Run()
}
public void Run(Action actionToRun)
{
Before();
actionToRun();
After();
}
protected virtual void After()
{
// Executed after Run()
}
}
Which you can call like this:
public void OneOfYourMethods()
{
// your code
}
public void RunYourMethod()
{
new BeforeAndAfterRunner().Run(OneOfYourMethods);
}
To literally achieve what you want, you can use a delegate:
Action<Action> callWithWrap = f => {
Console.WriteLine("Before stuff");
f();
Console.WriteLine("After stuff");
};
callWithWrap(() => {
Console.WriteLine("This is stuff");
});
This requires adding "weird syntax" to your blocks and an understanding of how delegates and anonymous functions in C# work. More commonly, if you're doing this within a class, use the technique demonstrated in #CodeCaster's answer.

Modify an attribute of a thread from other class

I have an problem with my code. I have 2 classes:
clsSMS
clsWorker
When my thread is running, I want to modify an attribute of them from my clsSMS class.
public class clsSMS
{
clsWorker objclsWorker;
public clsSMS(clsWorker objclsWorker = null)
{
this.objclsWorker.operatorBlocageError38();
// The above call doesn't work...
// I think the objclsWorker is always null...
// What do you think?
}
}
public class clsWorker
{
public clsSMS clsobjSMS;
public clsWorker(...)
{
this.clsobjSMS = new clsSMS(objclsWorker: this);
}
public void operatorBlocageError38(/*String port_concerne, bool erreur38*/)
{
MessageBox.Show("The method call work fine!");
}
}
It doesn't appear from the posted code that you ever instantiated clsWorker.
clsWorker worker = new clsWorker();
worker.operatorBlocageError38();
If you call operatorBlocageError38 before instantiating, the method has to be marked static.
public static void operatorBlocageError38()

Categories

Resources