Record Time Custom Attribute C# [duplicate] - c#

Is there a way in C# or .NET in general to create an attribute on a method which triggers an event when the method is invoked? Ideally, I would be able to run custom actions before and after the invocation of the method.
I mean something like this:
[TriggersMyCustomAction()]
public void DoSomeStuff()
{
}
I am totally clueless how to do it or if it possible at all, but System.Diagnostic.ConditionalAttribute might do a similar thing in the background. I am not sure though.
EDIT: I forgot to mention that due to the circumstances of my specific case, performance is not really an issue.

This concept is used in MVC web applications.
The .NET Framework 4.x provides several attributes which trigger actions, e.g.: ExceptionFilterAttribute (handling exceptions), AuthorizeAttribute (handling authorization). Both are defined in System.Web.Http.Filters.
You could for instance define your own authorization attribute as follows:
public class myAuthorizationAttribute : AuthorizeAttribute
{
protected override bool IsAuthorized(HttpActionContext actionContext)
{
// do any stuff here
// it will be invoked when the decorated method is called
if (CheckAuthorization(actionContext))
return true; // authorized
else
return false; // not authorized
}
}
Then, in your controller class you decorate the methods which are supposed to use your authorization as follows:
[myAuthorization]
public HttpResponseMessage Post(string id)
{
// ... your code goes here
response = new HttpResponseMessage(HttpStatusCode.OK); // return OK status
return response;
}
Whenever the Post method is invoked, it will call the IsAuthorized method inside the myAuthorization Attribute before the code inside the Post method is executed.
If you return false in the IsAuthorized method, you signal that authorization is not granted and the execution of the method Post aborts.
To understand how this works, let's look into a different example: The ExceptionFilter, which allows filtering exceptions by using attributes, the usage is similar as shown above for the AuthorizeAttribute (you can find a more detailed description about its usage here).
To use it, derive the DivideByZeroExceptionFilter class from the ExceptionFilterAttribute as shown here, and override the method OnException:
public class DivideByZeroExceptionFilter : ExceptionFilterAttribute
{
public override void OnException(HttpActionExecutedContext actionExecutedContext)
{
if (actionExecutedContext.Exception is DivideByZeroException)
{
actionExecutedContext.Response = new HttpResponseMessage() {
Content = new StringContent("A DIV error occured within the application.",
System.Text.Encoding.UTF8, "text/plain"),
StatusCode = System.Net.HttpStatusCode.InternalServerError
};
}
}
}
Then use the following demo code to trigger it:
[DivideByZeroExceptionFilter]
public void Delete(int id)
{
// Just for demonstration purpose, it
// causes the DivideByZeroExceptionFilter attribute to be triggered:
throw new DivideByZeroException();
// (normally, you would have some code here that might throw
// this exception if something goes wrong, and you want to make
// sure it aborts properly in this case)
}
Now that we know how it is used, we're mainly interested in the implementation. The following code is from the .NET Framework. It uses the interface IExceptionFilter internally as a contract:
namespace System.Web.Http.Filters
{
public interface IExceptionFilter : IFilter
{
// Executes an asynchronous exception filter.
// Returns: An asynchronous exception filter.
Task ExecuteExceptionFilterAsync(
HttpActionExecutedContext actionExecutedContext,
CancellationToken cancellationToken);
}
}
The ExceptionFilterAttribute itself is defined as follows:
namespace System.Web.Http.Filters
{
// Represents the attributes for the exception filter.
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method,
Inherited = true, AllowMultiple = true)]
public abstract class ExceptionFilterAttribute : FilterAttribute,
IExceptionFilter, IFilter
{
// Raises the exception event.
// actionExecutedContext: The context for the action.
public virtual void OnException(
HttpActionExecutedContext actionExecutedContext)
{
}
// Asynchronously executes the exception filter.
// Returns: The result of the execution.
Task IExceptionFilter.ExecuteExceptionFilterAsync(
HttpActionExecutedContext actionExecutedContext,
CancellationToken cancellationToken)
{
if (actionExecutedContext == null)
{
throw Error.ArgumentNull("actionExecutedContext");
}
this.OnException(actionExecutedContext);
return TaskHelpers.Completed();
}
}
}
Inside ExecuteExceptionFilterAsync, the method OnException is called. Because you have overridden it as shown earlier, the error can now be handled by your own code.
There is also a commercial product available as mentioned in OwenP's answer, PostSharp, which allows you to do that easily. Here is an example how you can do that with PostSharp. Note that there is an Express edition available which you can use for free even for commercial projects.
PostSharp Example (see the link above for full description):
public class CustomerService
{
[RetryOnException(MaxRetries = 5)]
public void Save(Customer customer)
{
// Database or web-service call.
}
}
Here the attribute specifies that the Save method is called up to 5 times if an exception occurs. The following code defines this custom attribute:
[PSerializable]
public class RetryOnExceptionAttribute : MethodInterceptionAspect
{
public RetryOnExceptionAttribute()
{
this.MaxRetries = 3;
}
public int MaxRetries { get; set; }
public override void OnInvoke(MethodInterceptionArgs args)
{
int retriesCounter = 0;
while (true)
{
try
{
args.Proceed();
return;
}
catch (Exception e)
{
retriesCounter++;
if (retriesCounter > this.MaxRetries) throw;
Console.WriteLine(
"Exception during attempt {0} of calling method {1}.{2}: {3}",
retriesCounter, args.Method.DeclaringType, args.Method.Name, e.Message);
}
}
}
}

The only way I know how to do this is with PostSharp. It post-processes your IL and can do things like what you asked for.

You need some sort of Aspect oriented framework. PostSharp will do it, as will Windsor.
Basically, they subclass your object and override this method...
then it becomes:
//proxy
public override void DoSomeStuff()
{
if(MethodHasTriggerAttribute)
Trigger();
_innerClass.DoSomeStuff();
}
of course all this is hidden to you. All you have to do is ask Windsor for the type, and it will do the proxying for you. The attribute becomes a (custom) facility I think in Windsor.

You can use ContextBoundObject and IMessageSink. See http://msdn.microsoft.com/nb-no/magazine/cc301356(en-us).aspx
Be warned that this approach has a severe performance impact compared with a direct method call.

I don't think there is a way to do it with just an attribute, but using proxy classes and reflection you could have a class that knows to intercept instantiations of the classes in which you have attributed methods.
Then the proxy class can trigger an event whenever the attributed methods are called.

An attribute gives information, they are metadata. I don't know of a way to do this offhand, someone might.
You could look at partial methods in .NET which allow you to do some lightweight event handling. You provide the hooks and let someone else handle the implementation. If the method isn't implemented the compiler just ignores it.
http://msdn.microsoft.com/en-us/library/wa80x488.aspx

You might take a look at the poor man's solution: see the decorator pattern.

Related

How to infer inline code using a method attribute [duplicate]

Is there a way in C# or .NET in general to create an attribute on a method which triggers an event when the method is invoked? Ideally, I would be able to run custom actions before and after the invocation of the method.
I mean something like this:
[TriggersMyCustomAction()]
public void DoSomeStuff()
{
}
I am totally clueless how to do it or if it possible at all, but System.Diagnostic.ConditionalAttribute might do a similar thing in the background. I am not sure though.
EDIT: I forgot to mention that due to the circumstances of my specific case, performance is not really an issue.
This concept is used in MVC web applications.
The .NET Framework 4.x provides several attributes which trigger actions, e.g.: ExceptionFilterAttribute (handling exceptions), AuthorizeAttribute (handling authorization). Both are defined in System.Web.Http.Filters.
You could for instance define your own authorization attribute as follows:
public class myAuthorizationAttribute : AuthorizeAttribute
{
protected override bool IsAuthorized(HttpActionContext actionContext)
{
// do any stuff here
// it will be invoked when the decorated method is called
if (CheckAuthorization(actionContext))
return true; // authorized
else
return false; // not authorized
}
}
Then, in your controller class you decorate the methods which are supposed to use your authorization as follows:
[myAuthorization]
public HttpResponseMessage Post(string id)
{
// ... your code goes here
response = new HttpResponseMessage(HttpStatusCode.OK); // return OK status
return response;
}
Whenever the Post method is invoked, it will call the IsAuthorized method inside the myAuthorization Attribute before the code inside the Post method is executed.
If you return false in the IsAuthorized method, you signal that authorization is not granted and the execution of the method Post aborts.
To understand how this works, let's look into a different example: The ExceptionFilter, which allows filtering exceptions by using attributes, the usage is similar as shown above for the AuthorizeAttribute (you can find a more detailed description about its usage here).
To use it, derive the DivideByZeroExceptionFilter class from the ExceptionFilterAttribute as shown here, and override the method OnException:
public class DivideByZeroExceptionFilter : ExceptionFilterAttribute
{
public override void OnException(HttpActionExecutedContext actionExecutedContext)
{
if (actionExecutedContext.Exception is DivideByZeroException)
{
actionExecutedContext.Response = new HttpResponseMessage() {
Content = new StringContent("A DIV error occured within the application.",
System.Text.Encoding.UTF8, "text/plain"),
StatusCode = System.Net.HttpStatusCode.InternalServerError
};
}
}
}
Then use the following demo code to trigger it:
[DivideByZeroExceptionFilter]
public void Delete(int id)
{
// Just for demonstration purpose, it
// causes the DivideByZeroExceptionFilter attribute to be triggered:
throw new DivideByZeroException();
// (normally, you would have some code here that might throw
// this exception if something goes wrong, and you want to make
// sure it aborts properly in this case)
}
Now that we know how it is used, we're mainly interested in the implementation. The following code is from the .NET Framework. It uses the interface IExceptionFilter internally as a contract:
namespace System.Web.Http.Filters
{
public interface IExceptionFilter : IFilter
{
// Executes an asynchronous exception filter.
// Returns: An asynchronous exception filter.
Task ExecuteExceptionFilterAsync(
HttpActionExecutedContext actionExecutedContext,
CancellationToken cancellationToken);
}
}
The ExceptionFilterAttribute itself is defined as follows:
namespace System.Web.Http.Filters
{
// Represents the attributes for the exception filter.
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method,
Inherited = true, AllowMultiple = true)]
public abstract class ExceptionFilterAttribute : FilterAttribute,
IExceptionFilter, IFilter
{
// Raises the exception event.
// actionExecutedContext: The context for the action.
public virtual void OnException(
HttpActionExecutedContext actionExecutedContext)
{
}
// Asynchronously executes the exception filter.
// Returns: The result of the execution.
Task IExceptionFilter.ExecuteExceptionFilterAsync(
HttpActionExecutedContext actionExecutedContext,
CancellationToken cancellationToken)
{
if (actionExecutedContext == null)
{
throw Error.ArgumentNull("actionExecutedContext");
}
this.OnException(actionExecutedContext);
return TaskHelpers.Completed();
}
}
}
Inside ExecuteExceptionFilterAsync, the method OnException is called. Because you have overridden it as shown earlier, the error can now be handled by your own code.
There is also a commercial product available as mentioned in OwenP's answer, PostSharp, which allows you to do that easily. Here is an example how you can do that with PostSharp. Note that there is an Express edition available which you can use for free even for commercial projects.
PostSharp Example (see the link above for full description):
public class CustomerService
{
[RetryOnException(MaxRetries = 5)]
public void Save(Customer customer)
{
// Database or web-service call.
}
}
Here the attribute specifies that the Save method is called up to 5 times if an exception occurs. The following code defines this custom attribute:
[PSerializable]
public class RetryOnExceptionAttribute : MethodInterceptionAspect
{
public RetryOnExceptionAttribute()
{
this.MaxRetries = 3;
}
public int MaxRetries { get; set; }
public override void OnInvoke(MethodInterceptionArgs args)
{
int retriesCounter = 0;
while (true)
{
try
{
args.Proceed();
return;
}
catch (Exception e)
{
retriesCounter++;
if (retriesCounter > this.MaxRetries) throw;
Console.WriteLine(
"Exception during attempt {0} of calling method {1}.{2}: {3}",
retriesCounter, args.Method.DeclaringType, args.Method.Name, e.Message);
}
}
}
}
The only way I know how to do this is with PostSharp. It post-processes your IL and can do things like what you asked for.
You need some sort of Aspect oriented framework. PostSharp will do it, as will Windsor.
Basically, they subclass your object and override this method...
then it becomes:
//proxy
public override void DoSomeStuff()
{
if(MethodHasTriggerAttribute)
Trigger();
_innerClass.DoSomeStuff();
}
of course all this is hidden to you. All you have to do is ask Windsor for the type, and it will do the proxying for you. The attribute becomes a (custom) facility I think in Windsor.
You can use ContextBoundObject and IMessageSink. See http://msdn.microsoft.com/nb-no/magazine/cc301356(en-us).aspx
Be warned that this approach has a severe performance impact compared with a direct method call.
I don't think there is a way to do it with just an attribute, but using proxy classes and reflection you could have a class that knows to intercept instantiations of the classes in which you have attributed methods.
Then the proxy class can trigger an event whenever the attributed methods are called.
An attribute gives information, they are metadata. I don't know of a way to do this offhand, someone might.
You could look at partial methods in .NET which allow you to do some lightweight event handling. You provide the hooks and let someone else handle the implementation. If the method isn't implemented the compiler just ignores it.
http://msdn.microsoft.com/en-us/library/wa80x488.aspx
You might take a look at the poor man's solution: see the decorator pattern.

How can I write Interceptor (AOP) with Castle Core or Other libraries (just free libraries) for Cross Cutting Concerns

I want to have an attribute like this for Cross Cutting Concerns like Logging , Exception , ...
public class MyService
{
[Log] // Interception (AOP)
[ExceptionHandler] // Interception (AOP)
public void DoSomething()
{
}
}
I know that I can write these codes with postsharp but I want to write these interceptions with free libraries like Castle Core and ...
Can anyone help me and write a sample for these purpose ???
I need a very simple sample for learning concepts
Autofac is a free IoC container. I use Autofac with Autofac.Extras.DynamicProxy2 nuget, docs.
Assuming you know why and when to (and not to) use interceptors, and you want to intercept some functionality:
public class FooService : IFooService
{
public void MoreFoo()
{
DoSomething();
}
public void LessFoo()
{
DoSomethingElse();
}
}
It needs to be "wired". I like attributes as you don't need to explicitly specify the interceptor at IoC container wiring. You just specify an attribute to watch out for:
[Intercept(typeof(Logger)]
public class FooService : IFooService { ... }
and wire it:
var builder = new ContainerBuilder();
builder.RegisterType<FooService>()
.EnableClassInterceptors();
Then create your Logger interceptor in another file:
class Logger : IInterceptor
{
public void Intercept(IInvocation invocation) // implements the IInterceptor interface
{
_loggerService.Log("calling " + invocation.Method.Name);
invocation.Proceed();
_loggerService.Log("finished " + invocation.Method.Name);
}
}
As you can see, you can create timers, try-catch blocks, and much more. Database context and other disposable resources is an interesting one:
class Logger : IInterceptor
{
public void Intercept(IInvocation invocation) // implements the IInterceptor interface
{
using (var someThing = new SomeResource())
{
invocation.Proceed();
}
}
}
Usually with such a resource you need to use someThing inside your method. That's a topic for another question! (see invocation.SetArgumentValue or invocation.TargetType.GetProperties() to communicate to the enclosing class. I'm not 100% comfortable with this, so some comments from others would be helpful)
Then, take a logging as an example:
void ManageFoo()
{
// sorry for the messy code, what else can I do?!
_logger("more foo please");
_fooService.MoreFoo();
_logger("less foo please");
_fooService.LessFoo();
_logger("enough foo");
}
The actual concern of the ManageFoo method is lost in all the mess of logging (add security and other concerns and you can end up with a big mess).
Now you can rewrite it like this:
void ManageFoo()
{
_fooService.MoreFoo();
_fooService.LessFoo();
}
Java has AOP with aspectJ and weaving (LTW load time with a proxy, and complile time CTW)
C# (Castle) has intersceptors, that use a (dynamic) proxy as well. You can see it as the LTW variant.
I used this setup in c#.
It is no big magic, and quite limited code.
Autofac 5.1.0
Autofac.Extras.DynamicProxy 5.0.0
Castle.Core 4.4.0
The trick is to
define some attibute, that you use as intersceptor attribute
define a intersceptor, that checks for the attribute on the method called
define a interface with a method and the attribute on the interface method
define implementation class of the interface
register the whole setup with autofac
test/run/go
1) define some attibute
using System;
[AttributeUsage(
AttributeTargets.Method,
AllowMultiple = true)]
public class SomeAttribute : Attribute
{
public long Id { get; set; }
}
2) Define a Castle dynamic intersceptor (aka proxy)
using Castle.DynamicProxy;
using System;
public class SomeInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
if (Attribute.IsDefined(invocation.Method, typeof(SomeAttribute)))
{
Console.Write("Method called: " + invocation.Method.Name);
}
invocation.Proceed();
}
}
Now, create a object with a interface (dont forget, put the attribute on the interface, not on the impl!)
3) define a interface
public interface AOPTest
{
[Some(Id = 10)]
void DoSomething();
}
4) define implementation :
public class AOPTestImpl : AOPTest
{
public void DoSomething()
{
}
}
5) register the whole setup with autofac
builder.RegisterType<AOPTestImpl>()
.As<AOPTest>()
.EnableInterfaceInterceptors()
.InterceptedBy(typeof(SomeInterceptor));
builder.RegisterType<SomeInterceptor>().AsSelf();
6) test/run/go : run the whole setup:
using Autofac;
using Autofac.Extras.DynamicProxy;
using (var scope = bootstrap.BootStrap.Container.BeginLifetimeScope())
{
var aOPTest = scope.Resolve<AOPTest>();
aOPTest.DoSomething();
}
I dont know how it excactly works but the idea is:
interface -> proxy -> implementation
So if you call the implementation over the interface, the proxy/intersceptor is in between.
Note: If you call other code inside the doSomething() method that needs intersception as well, you probably need a autofac class intersceptor EnableClassInterceptors
Note: it is not the fastest solution in the world. Probably some filtering intersceptor is faster, and compile time weaving like Fody or PostSharp are probably faster. But this will do a lot of times.
Note: if you need something done #Before start of the method, code it before the invocation.Proceed(); If you need something done at the end, code it if #After the invocation.Proceed() call:
#Before
DoSomething(){...}
#After
This lib does what you need https://github.com/pamidur/aspect-injector
[LogCall]
public void Calculate()
{
Console.WriteLine("Calculated");
}
ps. shameless self-ad
if you want to use runtime aop , you can try https://fs7744.github.io/Norns.Urd/index.html
it is very simple, a Interceptor like:
public class ConsoleInterceptor : AbstractInterceptor
{
public override async Task InvokeAsync(AspectContext context, AsyncAspectDelegate next)
{
Console.WriteLine($"{context.Service.GetType().GetReflector().FullDisplayName}.{context.Method.GetReflector().DisplayName}");
await next(context);
}
}

How do I make attributes on a base class method apply in the inherited class?

Note: This question has been updated with new info. Please see the bottom half of this text. (The original quesiton is left here for context.)
Is there any way I can define my attribute so that if it's defined on a method that is overidden, the attribute is still applied?
The reason I ask is that I have an attribute which injects some behavior into the method, but the behavior is not applied when the method is called as in any of the cases in the child class, and I would like it to be.
class BaseClass
{
[MyThing]
virtual void SomeMethod()
{
// Do something fancy because of the attribute.
}
}
class ChildClass
{
override void SomeMethod()
{
// Fancy stuff does happen here too...
base.SomeMethod();
}
void AnotherMethod()
{
// ...but not here. And I'd like it to =(
base.SomeMethod();
}
}
The attribute is defined like so:
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class MyThingAttribute : Attribute
The current code for finding methods with the attribute is the following:
var implementation = typeof(TheTypeWereCurrentlyInvestigating);
var allMethods = (from m in implementation.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy)
let attribs = (TransactionAttribute[]) m.GetCustomAttributes(typeof (TransactionAttribute), true)
where attribs.Length > 0
select Tuple.Create(m, attribs.Length > 0 ? attribs[0] : null)).ToList();
I didn't write that part, and I can't say I am 100% of what every part of it does... But we can assume, for now, that I am in control of all the involved code. (It's an opensource project, so I can at least create my own version, and submit a patch to the project owners...)
I have a couple of other cases too - basically I want to have this behavior injected whenever I call the method on the base class, no matter which way I got there - but if I solve this one I might get ideas on how to get the others working. If not, I'll get back with them.
UPDATE:
OK, so I sat down with the Castle.Transactions project and created some very simple tests to see what works and what doesn't. It turns out that my original assumptions on what works and what doesn't were somewhat off.
What I did:
I created a test class which has one method, decorated with the attribute, and which calls an Assert method that verifies that the behavior was injected correctly (i.e. that there is a transaction). I then created a couple of classes which inherit this test class, to see in which cases everything works as I expect it to.
What I found:
By calling the test method directly on the test class and from various methods on the child classes, I discovered the following about what works and what doesn't:
Method called Access modifiers Does it work?
************* **************** *************
SomeMethod() on base class* N/A Yes
OtherMethod() on child neither NO <-- headache!
OtherMethod() on child hiding (new) No
SomeMethod() on child hiding (new) No
OtherMethod() on child overrides No
OtherMethod() on child* overrides Yes
SomeMethod() on child overrides Yes
In all cases except the one marked with *, base.SomeMethod() was called from the method applied in the test. In the first case the same method was called but directly from the test, since no child class is involved. In the second case (of the ones marked *), the overriding method was called, i.e. this.SomeMethod(), so that's really equivalent of the last case. I'm not using any redundant qualifiers, so in that method the call is simply SomeMethod().
What I want:
It's the case marked "headache" that I really want to solve; how to inject behavior into the base class even though I'm calling it from my child class.
The reason I need that specific case to work is that I'm using this pattern in a repository, where the base class defines a Save(T entity) method decorated with the Transaction attribute. Currently, I have to override this method just to get the transaction orchestration, which makes it impossible to change the return type; on the base class it's void, but on my implementation I'd like to make it Error<T> instead. This is impossible when overriding, and since I can't solve the problem by naming the method differently, I'm at a loss.
If I were you I'd try and change your design. Calling base.SomeMethod() in AnotherMethod() when it has been overridden in AnotherMethod's class really smells.
Can't you factor out in a protected method the relevant part of BaseClass.SomeMethod(), place your attribute on this new method and call it in BaseClass.SomeMethod() and AnotherMethod(), assuming ChildClass.SomeMethod() would still call the method it overrides?
Can't go over it. Can't go under it. Gotta go around it.
Considering your circumstances as I understand them:
Can't apply the existing attribute to inject commit/rollback: It would never roll back because you're catching exceptions yourself in AnotherMethod().
You need the commit/rollback injection in AnotherMethod().
I suspect that TransactionAttribute is wrapping the method's body in a try-catch block, transforming this (pseudocode):
public void SomeMethod() {
DoStuff();
}
Into something like this (pseudocode, and very simplified):
public void SomeMethod() {
transaction.Begin();
try {
DoStuff();
transaction.Commit();
}
catch {
transaction.Rollback();
}
}
With that in mind, you may be able to apply TransactionAttribute to AnotherMethod() and re-throw the exceptions you catch:
[TransactionAttribute]
public void AnotherMethod() {
try {
DoStuff();
}
catch (Exception ex) {
//deal with exception
throw;
}
}
If that is not feasible -- such as if you only want part of the behavior that TransactionAttribute injects -- then you will likely have to make a new TransactionAttribute that injects the behavior you want it to inject. One possibility might be that it looks for try-catch blocks and places commits and rollbacks in the appropriate places, but that could be trickier than the current version.
Shot in the dark here, but...
I am assuming that the transaction behavior is injected by an IoC container, and that it does this by making a proxy when you resolve a ChildClass. Therefore the transaction code runs before\after ChildClass.SomeMethod via the proxy. I'm guessing that the behavior you're seeing is that there is no code injection on BaseClass.SomeMethod, so calling it from ChildClass.AnotherMethod does not involve any proxy code injection, it just goes straight through.
If this is the case, you could use a composition pattern and injection of a BaseClass to solve the problem.
If you resolved the following class via your container, it would inject a proxied BaseClass which had the appropriate before\after transaction code for BaseClass.SomeMethod method. You would therefore get your transaction behavior, plus your graceful exception handling.
You can play around with the usual OO mechanisms to sort out the issue of making AnotherChildClass interchangeable for a BaseClass, or use an interface, etc, etc.
public class AnotherChildClass
{
private readonly BaseClass _bling;
public AnotherChildClass(BaseClass bling)
{
_bling = bling;
}
public void AnotherMethod()
{
try
{
_bling.SomeMethod();
}
catch (Exception)
{
//Do nothing...
}
}
}
For example, a bit urgh, but you get the picture:
public class AnotherChildClass : BaseClass
{
private readonly BaseClass _bling;
public AnotherChildClass(BaseClass bling)
{
_bling = bling;
}
public override void SomeMethod()
{
_bling.SomeMethod();
}
public void AnotherMethod()
{
try
{
_bling.SomeMethod();
}
catch (Exception)
{
//Do nothing...
}
}
}
Update
I'm guessing that from your latest investigations the cases where you have used 'new' are not working as you are now blocking the generated IoC container proxy from overriding SomeMethod and therefore injecting the code. Try creating a derived class of your Child class, and try overriding the new SomeMethod method. This illustrates how the proxy is blocked.
private class BaseClass
{
public virtual void SomeMethod(){}
}
private class ChildClass : BaseClass
{
public new void SomeMethod() //<- Declaring new method will block proxy
{
base.SomeMethod();
}
}
private class ChildClassIocProxy : ChildClass
{
public override void SomeMethod() //<-- Not possible!
{
//Injected - before Tx
base.SomeMethod();
//Injected - after Tx
}
}

Finding all methods with missing security check

I am working on a code review. We have code that looks similar to this:
public int MyMethod(Message message)
{
// Check that the user has the access to the function
CheckUserHasAccessToFunction(UserName, FunctionName);
// Do the work
}
What I am wondering is: Is it possible to find all methods where the "CheckUserHasAccessToFunction" is missing. For example using regular expressions.
Which function name we test against will vary from method to method. The mapping between the function name and the method is part of the business logic, which we have implemented in code.
I think you should refactor your code in a way that you do not need to include this security check manually in every method, because - as you see - you cannot be sure if all methods perform this security check.
Have you ever worked with proxies? If so, you could add an interceptor which checks the security for you automatically. If not, tell me, then I will give you an example code snippet.
Edit: Here is a code sample which uses proxies (using Castle.DynamicProxy).
public class MyService
{
// The method must be virtual.
public virtual DoSomethingWhichRequiresAuthorization()
{
}
}
public static class MyServiceFactory
{
private static ProxyGenerator _generator;
private static ProxyGenerator Generator
{
get
{
if (_generator == null) _generator = new ProxyGenerator();
return _generator;
}
}
public static MyService Create()
{
var interceptor = new AuthorizationInterceptor();
return (MyService)Generator.CreateClassProxy(
typeof(MyService), new[] { interceptor });
}
}
public class AuthorizationInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
// invocation.Method contains the MethodInfo
// of the actually called method.
AuthorizeMethod(invocation.Method);
}
}
You would probably be better off using Attributes for this, in my opinion.
E.g.
[RequiresAuth]
public void Method()
{
}
I know this doesn't answer your question well, so apologies for that.

C#: How to create an attribute on a method triggering an event when it is invoked?

Is there a way in C# or .NET in general to create an attribute on a method which triggers an event when the method is invoked? Ideally, I would be able to run custom actions before and after the invocation of the method.
I mean something like this:
[TriggersMyCustomAction()]
public void DoSomeStuff()
{
}
I am totally clueless how to do it or if it possible at all, but System.Diagnostic.ConditionalAttribute might do a similar thing in the background. I am not sure though.
EDIT: I forgot to mention that due to the circumstances of my specific case, performance is not really an issue.
This concept is used in MVC web applications.
The .NET Framework 4.x provides several attributes which trigger actions, e.g.: ExceptionFilterAttribute (handling exceptions), AuthorizeAttribute (handling authorization). Both are defined in System.Web.Http.Filters.
You could for instance define your own authorization attribute as follows:
public class myAuthorizationAttribute : AuthorizeAttribute
{
protected override bool IsAuthorized(HttpActionContext actionContext)
{
// do any stuff here
// it will be invoked when the decorated method is called
if (CheckAuthorization(actionContext))
return true; // authorized
else
return false; // not authorized
}
}
Then, in your controller class you decorate the methods which are supposed to use your authorization as follows:
[myAuthorization]
public HttpResponseMessage Post(string id)
{
// ... your code goes here
response = new HttpResponseMessage(HttpStatusCode.OK); // return OK status
return response;
}
Whenever the Post method is invoked, it will call the IsAuthorized method inside the myAuthorization Attribute before the code inside the Post method is executed.
If you return false in the IsAuthorized method, you signal that authorization is not granted and the execution of the method Post aborts.
To understand how this works, let's look into a different example: The ExceptionFilter, which allows filtering exceptions by using attributes, the usage is similar as shown above for the AuthorizeAttribute (you can find a more detailed description about its usage here).
To use it, derive the DivideByZeroExceptionFilter class from the ExceptionFilterAttribute as shown here, and override the method OnException:
public class DivideByZeroExceptionFilter : ExceptionFilterAttribute
{
public override void OnException(HttpActionExecutedContext actionExecutedContext)
{
if (actionExecutedContext.Exception is DivideByZeroException)
{
actionExecutedContext.Response = new HttpResponseMessage() {
Content = new StringContent("A DIV error occured within the application.",
System.Text.Encoding.UTF8, "text/plain"),
StatusCode = System.Net.HttpStatusCode.InternalServerError
};
}
}
}
Then use the following demo code to trigger it:
[DivideByZeroExceptionFilter]
public void Delete(int id)
{
// Just for demonstration purpose, it
// causes the DivideByZeroExceptionFilter attribute to be triggered:
throw new DivideByZeroException();
// (normally, you would have some code here that might throw
// this exception if something goes wrong, and you want to make
// sure it aborts properly in this case)
}
Now that we know how it is used, we're mainly interested in the implementation. The following code is from the .NET Framework. It uses the interface IExceptionFilter internally as a contract:
namespace System.Web.Http.Filters
{
public interface IExceptionFilter : IFilter
{
// Executes an asynchronous exception filter.
// Returns: An asynchronous exception filter.
Task ExecuteExceptionFilterAsync(
HttpActionExecutedContext actionExecutedContext,
CancellationToken cancellationToken);
}
}
The ExceptionFilterAttribute itself is defined as follows:
namespace System.Web.Http.Filters
{
// Represents the attributes for the exception filter.
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method,
Inherited = true, AllowMultiple = true)]
public abstract class ExceptionFilterAttribute : FilterAttribute,
IExceptionFilter, IFilter
{
// Raises the exception event.
// actionExecutedContext: The context for the action.
public virtual void OnException(
HttpActionExecutedContext actionExecutedContext)
{
}
// Asynchronously executes the exception filter.
// Returns: The result of the execution.
Task IExceptionFilter.ExecuteExceptionFilterAsync(
HttpActionExecutedContext actionExecutedContext,
CancellationToken cancellationToken)
{
if (actionExecutedContext == null)
{
throw Error.ArgumentNull("actionExecutedContext");
}
this.OnException(actionExecutedContext);
return TaskHelpers.Completed();
}
}
}
Inside ExecuteExceptionFilterAsync, the method OnException is called. Because you have overridden it as shown earlier, the error can now be handled by your own code.
There is also a commercial product available as mentioned in OwenP's answer, PostSharp, which allows you to do that easily. Here is an example how you can do that with PostSharp. Note that there is an Express edition available which you can use for free even for commercial projects.
PostSharp Example (see the link above for full description):
public class CustomerService
{
[RetryOnException(MaxRetries = 5)]
public void Save(Customer customer)
{
// Database or web-service call.
}
}
Here the attribute specifies that the Save method is called up to 5 times if an exception occurs. The following code defines this custom attribute:
[PSerializable]
public class RetryOnExceptionAttribute : MethodInterceptionAspect
{
public RetryOnExceptionAttribute()
{
this.MaxRetries = 3;
}
public int MaxRetries { get; set; }
public override void OnInvoke(MethodInterceptionArgs args)
{
int retriesCounter = 0;
while (true)
{
try
{
args.Proceed();
return;
}
catch (Exception e)
{
retriesCounter++;
if (retriesCounter > this.MaxRetries) throw;
Console.WriteLine(
"Exception during attempt {0} of calling method {1}.{2}: {3}",
retriesCounter, args.Method.DeclaringType, args.Method.Name, e.Message);
}
}
}
}
The only way I know how to do this is with PostSharp. It post-processes your IL and can do things like what you asked for.
You need some sort of Aspect oriented framework. PostSharp will do it, as will Windsor.
Basically, they subclass your object and override this method...
then it becomes:
//proxy
public override void DoSomeStuff()
{
if(MethodHasTriggerAttribute)
Trigger();
_innerClass.DoSomeStuff();
}
of course all this is hidden to you. All you have to do is ask Windsor for the type, and it will do the proxying for you. The attribute becomes a (custom) facility I think in Windsor.
You can use ContextBoundObject and IMessageSink. See http://msdn.microsoft.com/nb-no/magazine/cc301356(en-us).aspx
Be warned that this approach has a severe performance impact compared with a direct method call.
I don't think there is a way to do it with just an attribute, but using proxy classes and reflection you could have a class that knows to intercept instantiations of the classes in which you have attributed methods.
Then the proxy class can trigger an event whenever the attributed methods are called.
An attribute gives information, they are metadata. I don't know of a way to do this offhand, someone might.
You could look at partial methods in .NET which allow you to do some lightweight event handling. You provide the hooks and let someone else handle the implementation. If the method isn't implemented the compiler just ignores it.
http://msdn.microsoft.com/en-us/library/wa80x488.aspx
You might take a look at the poor man's solution: see the decorator pattern.

Categories

Resources