I have a CustomAuthorize attribute that checks to see if a user has access to functionality (a user or role can be associated with items from a hierarchical set of functions).
For a given action method...
[CustomAuthorize("Security.Admin.ManageWidgets.Update")]
This works but I'm concerned that changes to the Security object could cause problems that won't be detected until run-time. I realize that I can write unit tests to mitigate this risk but I would like to know if it is possible to check the attribute parameter at compile time. I also like having Intellisense help me type this expression.
Ideally, I could pass a lambda expression.
[CustomAuthorize(i => i.Admin.ManageWidgets.Update)]
Unfortunately this is not currently possible (additional info from Microsoft).
I also tried encapsulating the expression hoping it would be evaluated and then passed to the attribute as a string, but this also failed to compile with the same error (Expression cannot contain anonymous methods or lambda expressions).
[CustomAuthorize(LambdaToString(i => i.Admin.ManageWidgets.Update))]
How can I add some design-time / build-time support for my custom attribute parameters?
A Static class with constants.
public static class Rights
{
public const string UpdateWidgets = "UpdateWidgets";
}
Also include unittests for the methods which are decorated with them and you'll be pretty good.
[CustomAuthorize(Rights.UpdateWidgets)]
You can use T4 templates to create custom classes with string properties, ending up with code similar to BennyM's, but generated automatically.
No you can't check these sorts of things at compile time - the best you could hope for is a post-build step that checks this via reflection.
You could instead supply a type and a method name, like this:
[CustomAuthorize(typeof(Security.Admin.ManageWidgets), "Update")]
But seeing as you still need to type the name of the method its debatable what benefit this really gains you.
Related
Scenario:
I am trying to retrieve Custom Attributes from methods in a base class. The methods are async.
My base class implements virtual methods which contain default logic. Specifically, the class wraps an EF IRepository and exposes it as a Web API w/ Get/Post/Delete methods. Standard practice when subclassing this base is to add an attribute for Auth above the method override like [ResourceClaimsAuthorize(ResourceActions.Write, Resources.SomeResource)]. These attributes are what I'm trying to find.
Problems:
1) Because I'm in an async method, the AsyncStateMachine does it's thing and if I try to call MethodBase.GetCurrentMethod(), I will receive back "MoveNext()", rather than the actual method I'm in.
2) I've tried to use type.GetMethod(string methodName) instead. For this to work implicitly, I paired this approach with the [CallerMemberName] attribute which successfully grabs the method name. This partially worked - but broke the moment we encountered method overloads. It doesn't know how to determine which overload you want if overloads are present. This could be resolved by passing in an array of types to match the method signature of the overload we want - but I really don't want to muddy up our code by including an array of types into the logic - we're trying to reduce boiler plate and this feels like 1 step forward, 2 steps back.
3) I tried using a clever trick with Expression<Action<T>> as a method selector. In this approach, my base class calls my Auth logic and passes in a lambda which "selects" the method I want. like:
apiController => apiController.Post()
Then you can grab the method off the MethodCallExpression pretty easily by simply grabbing
expression.Body.Method; // this will be the methodinfo of the method you selected in your lambda
This almost worked -- however the MethodCallExpression isn't selecting the method of the derived class, the expression's type is the base class for some reason, not the derived class as I expected. In my situation, this results in only finding custom attributes from the base class version of the selected method; it is still ignorant of the custom attributes on the derived, overridden version of that method; which is what I need.
Is there a better way?
Ideally, I'd like to find my custom attributes just like I normally would, w/
var methodInfo = MethodBase.GetCurrentMethod();
var attributes = methodInfo.GetCustomAttributes<MyCustomAttribute>();
But the AyncStateMachine breaks that approach. Is there another way I can do that from inside an async method, that is just as easy? The GetCurrentMethod(string methodName) w/ [CallerMemberName] was almost a good fix if it weren't for the method overload naming collision, and the expression method selector approach almost worked if it weren't for it grabbing the base class method info instead of of the derived class method info.
Any ideas? Thanks for your time!
To anyone looking for the same thing that I was, I found a solution using #Jacek Gorgon's suggestion found here: MoveNext instead of actual method/task name
This allowed me to pass in the method info of the actual async method instead of an async state machine method. Jacek mentioned this isn't a good solution for production as it makes assumptions about the compiler which could change in the future. Unfortunately, this was the best way I had to solve my problem, without resorting to "no method overloads are allowed in our api controllers"
So far, so good!
It is valid (ie. it compiles and runs) to put an attribute on the generic parameter for a class or a method:
public class MyClass<[My] T>
{
private void MyMethod<[My] T>()
{}
}
public class MyAttribute : Attribute
{}
I've never seen this used, and am struggling to come up with a reason as to why you would want to.
Is it just a quirk/side-effect of the language specification, or is there a valid/useful reason to put an attribute in this position?
For the same reason attributes are useful on any construct; they supply meta-data that can be used by Reflection or other post-processors to do various things. For instance, you might have an AOP system that uses an attribute on a type argument to apply certain run-time constraints that otherwise could not be expressed. I'm not sure if there are any systems that actually use these attributes to do anything, but there's no reason to disallow them as metadata.
I'm sure some AOP nut will find a valid reason to decorate generic parameters with attributes. I certainly can't think of any. Try this:
typeof(MyClass<>).GetGenericArguments().GetCustomAttributes().OfType<MyAttribute>();
If this Enumerable has any elements, then it is possible to access the attribute you placed on the class's generic parameter. If not, then you can't and thus having data you'd expect to access from any other class in your codebase is pointless. HOWEVER, they can still have code that runs when instantiated, and they're instantiated by the runtime when the generic class comes into scope, allowing you to perform aspect-oriented logic in the attribute itself. Exactly what that would be, and how it would be any different than decorating the generic class or method directly, is left as an exercise to people who worship AOP far more than I do.
Alright, so after a few hours of me playing around to no avail, I built a model:
[AttributeUsage(AttributeTargets.All)]
public class PublicAttribute : System.Attribute
{
public enum Access { Public, Private }
public PublicAttribute(string Name, Access acs)
{
}
public PublicAttribute(string Name, Access acs, Action get, Action set)
{
}
}
So that if somebody were to do something like this:
[Public("PublicProperty", PublicAttribute.Access.Public)]
private string PrivateProperty = "hello";
or
[Public("PublicProperty", PublicAttribute.Access.Public, ()=>{return PrivateProperty;}, ()=>{PrivateProperty = value})]
private string PrivateProperty = "hello";
and then if somebody was trying to access PrivateProperty, they could just go:
ContainingClass.PublicProperty = //ect
"PublicProperty". and that is because of the attribute, and it would use those get/set accessors.
What I'd like to know:
Is this even possible?
Is there something that already does this?
If its possible, (even if there is something else) How do i do this?
Basically no to all 3, as C# is a strongly typed language. Even with duck typing what you're trying to achieve doesn't fit the language.
The attributes you've written allow you to interrogate the properties that have those attributes in the class, but you still need to use Reflection to discover which properties of the attribute class are set. The syntax you want to use is checked at compile-time.
No, this is not possible using attributes. Properties are part of the class metadata emitted by the C# compiler, and the C# compiler does not consider custom attributes.
You may be able to do this by using a post-processor such as PostSharp, which can rewrite your assembly after the fact, and can be instructed to consider custom attributes. However, you still wouldn't be able to include a delegate in the attribute: the set of types that can be stored in attribute state is extremely limited.
Microsoft made the WebMethodAttribute in a way reminiscent of what you're trying to describe making it represent more permission than C# public, effectively making a method available outside the application domain to the entire Internet (a very global scope). You might read it to get real implementation insight and ideas.
But you're hitting it very simply. You'll have to program some infrastructure to make it work. It's not automatic and you don't have access to Microsoft's source code for all the details.
I'm writing a .NET web application in which administrators can customize the various data entry forms presented to their users. There are about half a dozen different field types that admins can create and customize (i.e. text, numeric, dropdown, file upload). All fields share a set of base attributes/behaviors (is the field required? Will it have a default field value?). There are also a series of field specific attributes/behaviors (i.e dropdown has a data source attribute, but text field does not). I'm leaving out many other characteristics of the problem domain for simplicity's sake.
The class hierarchy is straightforward: An abstract superclass that encapsulates common behaviors/attributes and about half a dozen concrete subclasses that deal with field specific stuff.
Each field type is rendered (i.e. mapped to) as a specific type of .NET server control, all of which derive from System.Web.UI.Control.
I created the following code to map values between the field domain objects and their corresponding UI control:
public static void Bind(Control control, IList<DocumentFieldBase> fieldBaseList)
foreach (DocumentFieldBase fieldBase in fields){
if (typeof (DocumentFieldText).IsInstanceOfType(fieldBase)){
TextBox textbox = (TextBox) control;
textbox.Text = (fieldBase as DocumentFieldText).GetValue();
}
if (typeof (DocumentFieldDropDown).IsInstanceOfType(fieldBase)){
DropDown dropDown= (DropDown) control;
dropDown.Text = (fieldBase as DocumentFieldSelectOne).GetValue().Text;
dropDown.DataSource= (fieldBase as DocumentFieldSelectOne).DataSource;
dropDown.Id= (fieldBase as DocumentFieldSelectOne).GetValue().Id;
}
//more if statements left out for brevity
}
}
I want to ditch those ungodly if statements that perform type checking. The approach I was shooting for was to create a method overload for each combination of field/control using subclass typing. For example:
public static void Bind(TextBox control, DocumentFieldText fieldText){
//some implementation code
}
public static void Bind(DropDown control, DocumentFieldDropDown fieldDropDown){
//some implementation code
}
I was hoping that I could then rely on .NET to call the appropriate overload at runtime using the specific subclass being used: For example:
foreach (DocumentFieldBase field in fields){
Control control = FindControl(field.Identifier);
Bind(control, field)
}
Unfortunately, the compiler chokes when I try this:
Argument '1': cannot convert from 'System.Web.UI.Control' to 'TextBox'.
If I have to cast the first argument to TextBox, I'm back to performing type checking myself and defeats the whole purpose of this exercise.
Is what I'm trying to achieve a) possible and b) a good idea?
Prior to C# 4, all overloading is done at compile time. You have to use double dispatch or the visitor pattern to effectively overload at execution time, and that gets messy quickly.
In C# 4, you could declare a variable as dynamic and let it all get sorted out at execution time:
foreach (DocumentFieldBase field in fields){
dynamic control = FindControl(field.Identifier);
Bind(control, field)
}
Obviously that's not much help at the moment though (unless you're using VS2010b1).
One option is to use a map from Type to Action<object> but then you get inheritance issues... (you'd potentially have to keep working up the type hierarchy from the concrete type up to object until you found an entry in the map). You'd also still need to cast to the right type within the action :(
The "dispatch" tag on this question is quite appropriate: what you want is called "multiple dispatch". C# (like most mainstream languages) only supports "single dispatch", where the method to be executed is selected solely on the (runtime) type of the object you call the method on, not on the (runtime) type of its arguments.
The visitor pattern can often be used to work around this. The idea is that you give DocumentFieldBase a method (that you override in concrete subclasses) which calls a method on Control (also overridden in concrete subclasses) that does the actual work.
Unfortunately, the source code of the Control class is probably not under your control*... so you'll have to resort to an even more hackish solution. The accepted answer to this question provides one that uses reflection.
*Extension methods are just syntactic sugar for static methods, and are thus resolved at compile time and of no use in this scenario.
Couldn't you have an abstract, non-static Bind() method in DocumentFieldBase, then do the downcasting inside each concrete class's implementation of it? Each DocumentFieldBase class knows what type of Control it's getting, doesn't it?
I'm working on a method that accepts an expression tree as a parameter, along with a type (or instance) of a class.
The basic idea is that this method will add certain things to a collection that will be used for validation.
public interface ITestInterface
{
//Specify stuff here.
}
private static void DoSomething<T>(Expression<Func<T, object>> expression, params IMyInterface[] rule)
{
// Stuff is done here.
}
The method is called as follows:
class TestClass
{
public int MyProperty { get; set; }
}
class OtherTestClass : ITestInterface
{
// Blah Blah Blah.
}
static void Main(string[] args)
{
DoSomething<TestClass>(t => t.MyProperty,
new OtherTestClass());
}
I'm doing it this way because I'd like for the property names that are passed in to be strong typed.
A couple of things I'm struggling with..
Within DoSomething, I'd like to get a PropertyInfo type (from the body passed in) of T and add it to a collection along with rule[]. Currently, I'm thinking about using expression.Body and removing [propertyname] from "Convert.([propertyname])" and using reflection to get what I need. This seems cumbersome and wrong. Is there a better way?
Is this a specific pattern I'm using?
Lastly, any suggestions or clarifications as to my misunderstanding of what I'm doing are appreciated and / or resources or good info on C# expression trees are appreciated as well.
Thanks!
Ian
Edit:
An example of what expression.Body.ToString() returns within the DoSomething method is a string that contains "Convert(t.MyProperty)" if called from the example above.
I do need it to be strongly typed, so it will not compile if I change a property name.
Thanks for the suggestions!
I rely heavily on expression trees to push a lot of what I want to do with my current application to compile-time, i.e. static type checking.
I traverse expression trees to translate them into something else which "makes sense".
One thing I've ended up doing a lot is that instead of URLs I rely on a MVC like approach where I declare lambda functions, and translates that... interpret, the compiler generated expression tree into an URL. When this URL is invoked, I do the opposite. This way, I have what I call compile-time checks for broken links and this works great with refactoring and overloads as well. I think it's cool to think about using expression trees in this way.
You might wanna check out the visitor pattern, it's a pain to get started with because it doesn't make much sense in the beginning but it ties everything together and it's a very formal way to solve type checking in compiler construction. You could do the same, but instead of type checking emit what ever you need.
Something which I'm currently pounding my head against is the ability to build a simple framework for translating (or actually I should say interpret) expression tress and emit JavaScript. The idea is that the compiler generated expression trees will translate into valid JavaScript which interfaces with some object model.
What's exciting about this is the way the compiler is always able to tell me when I go wrong and sure the end result is just a bunch of strings but the important part is how these strings got created. They went through some verification and that means something.
Once you get that going there is little you can't do with expression trees.
While working with the System.Reflection.Emit stuff I found myself using expression trees to create a light-weight framework for dynamic compilation, which at compile time could basically say if my dynamically created assemblies would compile as well, and this worked seamlessly with reflection and static type checking. It took this further and further and ended up with something which in the end saved a lot of time and proved to be very agile and robust.
So I love this kind of stuff, and this is what meta programming is all about, writing programs in your programs that do programs. I say keep it coming!
Collecting PropertyInfo objects from Expression.Body seems similar to my solution to another question.
I appreciate what you are trying to do with the property here. I have run into this conundrum. It always feels weird to write:
DoSomething("MyProperty", new OtherClass());
If the property ever changes name, or the text is mistyped in the call, then there will be a problem. What I have come to learn is that this is something you probably have to deal with via testing. Specifically, unit testing. I would write unit tests to enforce that the "DoSomething" calls work correctly.
The other thing you might try is to decorate your properties with attributes, and then reflect against your class when it is constructed looking for properties with the attribute, and load rules.
[DoSomething(typeof(OtherClass), typeof(OtherClass2))]
public int MyProperty
{
get;
set;
}
In this case the constructor (perhaps in a base class?) would dynamically create an OtherClass object and a OtherClass2 object, and load them into a collection along with the name of the property.