C# Make a simple interception based on Attribute - c#

I would like to perform a C# interception based with Attribute by example:
[CheckSomething]
public void Test()
{
}
And I want to cancel the execution of the method by example, i've alreay tried by creating an Attribute, an other problem is that i don't arrive to Console.WriteLine() in the constructor of the Attribute, does anyone know why ?
Thank you

Related

How to create "filters" for class' methods?

With ASP.NET I have created a few filters extending both ExceptionFilterAttribute and ActionFilterAttribute. With ActionFilterAttribute I can execute actions before or after the method's execution. I'd like to mimic that behavior on my class. I have a base class called BaseService and whenever a method from this class is invoked I'd like to check if it contains an attribute and if it does execute that. For instance, on my derived classes I have methods like:
public void DoSomething()
{
LoggedUser.RequireAnyRole<RoleX, RoleY>("DoSomething");
// code here
}
public void DoSomething2()
{
LoggedUser.RequireRole<RoleX>("DoSomething2");
// code here
}
Instead of writing LoggedUser.RequireRole... I'd like it to be an attribute. That way I'd just add an attribute on top of DoSomething2: [RequireRole(Roles.X)].
Is this possible? If so, what is the best approach? I was reading something related to callmember, but I'm not sure that's the way to do it. I checked https://github.com/ASP-NET-MVC/aspnetwebstack for its implementation but I think I didn't know how to search for it since I didn't find anything...

Prevent certain classes to call certain methods using Attributes

I plan to give method calling privileges to certain classes in my program using Attributes but I just have no clude how to.
For example, here is what I want my Customer class to look like:
[ForbiddenMethodsAttr(listOfMyForbiddenMethods)]
public class Customer
{
public Customer { }
}
And if I want to call a given function, the intellisense should warm me that I can't, The reason I want to do this is because calling those functions may cause some issues and not I'm the only one who will code this project but some friends as well. So if it is possible to write such an attribute, how to do it?
You could mark the methods as obsolete and then anyone calling them will get a compiler warning (though not error). Its not elegant, but neither is attempting to restrict method calls without using scoping conventions.

How to use method parameter attributes

I've been struggling to find examples of how to write a custom attribute to validate method parameters, i.e., turn this form:
public void DoSomething(Client client)
{
if (client.HasAction("do_something"))
{
// ...
}
else
{
throw new RequiredActionException(client, "do_something");
}
}
into this:
public void DoSomething([RequiredAction(Action="some_action")] Client client)
{
// ...
}
As far as I can tell, I need to add this attribute to my custom attribute, but I'm at a loss on how to access the decorated parameter Client:
[AttributeUsageAttribute(AttributeTargets.Parameter)]
public class RequireActionAttribute : System.Attribute
{
public Type Action {get; set;}
public RequireActionAttribute()
{
// .. How do you access the decorated parameter?
Client client = ???
if (!client.HasAction(Action))
{
throw new RequiredActionException(client, Action);
}
}
}
You're applying it correctly - but an attribute basically doesn't know the member it refers to. This definitely makes life harder.
Not only does it not have access to the member that it refers to, but that member would be a ParameterInfo, not a Client - there's no easy way of accessing the value of a parameter externally. Your method would need to call some helper code, passing the value of client in order to handle it appropriately... or you need to hook into the code which is going to call your method to start with, in order to notice the attribute.
It's not clear exactly how you were hoping to use this, but it may well be that you need to change your design significantly.
Attributes are not enough for doing it.
If I understood you correctly you want to add an attribute on a parameter in order to validate it at run time and that is impossible only with attributes.
It is impossible because attributes are only "metadata" and not executed code.
You will need some "real" code to read it and act accordingly. That code can be injected at compile time or you can hook into the function execution.
Attributes probably should be put on the method itself. When I was searching for the solution I found the following link and the way it uses interceptor seems even better http://www.codinginstinct.com/2008/05/argument-validation-using-attributes.html

Custom Attribute invocation

I am trying with the Debugger to stop when a method attribute is invoked, but I am never seems to get to the break point.
Am I missing something here?
[SecurityImpl("test")]
public void test()
{
}
[AttributeUsage(AttributeTargets.All)]
public class SecurityImplAttribute : Attribute
{
public SecurityImplAttribute(string test)
{
//Break Point Here
}
}
Attributes are only metadata. They aren't actually created as instances unless you use reflection (GetCustomAttributes). You cannot use attributes to add arbitrary code calls, unless you use an AOP framework such as PostSharp, or are using a framework that checks for specific categories of attributes and instantiates/invokes them explicitly (like ASP.NET MVC does).
Attributes are only decorators and they do not execute by .net framework.
Attrubutes are just metadata for your code. They are not executed automatically. If you want to use some metadata, you should get it manually and execute it. In your case constructor of attribute will be executed when you'll try to get method custom attributes:
object[] attributes = methodInfo.GetCustomAttributes(true);
If you want some aspects to be executed automatically, when you invoke method, then you can use some AOP framework, like PostSharp. Here is an example of aspect creation, which executes some actions on method call:
[Serializable]
public class SecurityImplAttribute : OnMethodBoundaryAspect
{
public override void OnEntry(MethodExecutionArgs args)
{
// this code will be executed on method call
}
}
When you apply this attribute to some method, PostSharp will read method's metatada during compilation, and if aspect will be found, PostSharp will inject your code right into binaries.

How do I unit test private controller methods in ASP.NET MVC?

What is the best practice to unit-test private methods inside a controller in ASP.NET MVC? The Currently, if I want to unit-test a private method inside a controller I have to set it to public but when I do, that method is exposed to the web.
Is the best way to move the method to a helper class?
You should be moving the method into a helper class that you extracted an interface to. That way it's easier to perform dependency injection and switch the underlaying implementation or mock it if needed.
Testing private methods is a code smell (or a test smell).
Use InternalsVisibleTo trick only when you must (i.e. you are using an untestable class and must raise an event that is hidden from you by a protected function call).
You should use the private object, like this:
var privateObject = new PrivateObject(this.controller);
var result = (ActionResult)privateObject.Invoke("RegisterToEvent", shippingAddressID, creditCardID);
you could set the method to internal instead of private, and then set the InternalsVisibleTo attribute to the name of your test assembly.
In assembly info:
[assembly: InternalsVisibleTo("MyTestAssembly")]
You could create an action filter for test methods like this....
public class TestActionFilter : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
filterContext.HttpContext.Response.Redirect("loginurl");
//or throw exception or some other action
}
}
Or you could make the method only publicly accessible to another assembly.
[assembly: InternalsVisibleTo("TestAssembly")]
You can work around that problem by limiting tests to visible methods. Any private method will be used at least by one visible method (otherwise: it can safely be deleted).
So I suggest to develop tests that call the visible methods with practical values so that the private algorithms are tested. If code is not reachable through visible methods - delete it.
I have used the PrivateObject() method but I like Charlino's suggestion of NonActionAttribute (see comments to original question above), too.

Categories