We have a bunch of endpoints where we'd like to do the exact same thing for each of them:
Register them as a route and verify that the user has access to them. Very condensed our issue can be condensed to us having something like this:
[HttpGet, Route(EntityId.First)]
[HttpGet, Route(EntityId.Second)]
[VerifyAccessFilter(EntityId.First, EntityId.Second)]
public async Task<IActionResult> Endpoint()
{
return Ok();
}
But would much rather like something like:
[RouteAndVerify(EntityId.First, EntityId.Second)]
public async Task<IActionResult> Endpoint()
{
return Ok();
}
As you can tell this is very simplified, but I hope the intent gets across.
The hard part seems to be registering the route without using the default Route-attribute.
You can achieve this with a custom IActionModelConvention implementation. The official documentation explains the concept of an action model convention: Work with the application model in ASP.NET Core - Conventions. In a nutshell, by implementing IActionModelConvention, you can make changes to the application model and add filters, routes, etc to an action at runtime.
This is best explained with a sample implementation, which follows below. As you want to combine your existing MVC filter with the ability to configure routes for an action, the implementation below implements both IResourceFilter (this can be whatever filter type you're using) and IActionModelConvention:
public class VerifyAccessFilterAttribute : Attribute, IActionModelConvention, IResourceFilter
{
public VerifyAccessFilterAttribute(params string[] routeTemplates)
{
RouteTemplates = routeTemplates;
}
public string[] RouteTemplates { get; set; }
public void Apply(ActionModel actionModel)
{
actionModel.Selectors.Clear();
foreach (var routeTemplate in RouteTemplates)
{
actionModel.Selectors.Add(new SelectorModel
{
AttributeRouteModel = new AttributeRouteModel { Template = routeTemplate },
ActionConstraints = { new HttpMethodActionConstraint(new[] { "GET" }) }
});
}
}
public void OnResourceExecuting(ResourceExecutingContext ctx) { ... }
public void OnResourceExecuted(ResourceExecutedContext ctx) { ... }
}
In this example, it's all about the Apply method, which simply adds a new SelectorModel for each routeTemplate (as I've named it), each of which is constrained to HTTP GET requests.
Generally speaking, you cannot "merge" attributes, because attributes do not execute code. Attributes are only markers. Like "this method is marked red and blue". Then other code will come along, one looking for all red marks and doing something and another looking for all blue marks and doing something else. Building a purple mark by merging red and blue is just going to confuse the code looking for the markup, because purple is neither red nor blue.
However, AOP (aspect oriented programming) is available from third parties for C# and means attributes (called aspects because they do more than the normal marker attributes) can execute code.
You could write an aspect that decorates the method it's sitting on with the attributes you need, so you can write it once (and test it) and then you can set it on every method without worrying about forgetting an attribute or setting it wrong.
There are multiple AOP providers for C#, the most popular one seems to be PostSharp. You can see how write an aspect that adds attributes to a class or method at compile time with PostSharp here.
Related
I have a bunch of methods with varying signatures. These methods interact with a fragile data connection, so we often use a helper class to perform retries/reconnects, etc. Like so:
MyHelper.PerformCall( () => { doStuffWithData(parameters...) });
And this works fine, but it can make the code a little cluttery. What I would prefer to do is decorate the methods that interact with the data connection like so:
[InteractsWithData]
protected string doStuffWithData(parameters...)
{
// do stuff...
}
And then essentially, whenever doStuffWithData is called, the body of that method would be passed in as an Action to MyHelper.PerformCall(). How do I do this?
So, I just went to a AOP session this weekend, and here's a way to do it with PostSharp:
[Serializable]
public class MyAOPThing : MethodInterceptionAspect
{
public override void OnInvoke(MethodInterceptionArgs args)
{
Console.WriteLine("OnInvoke! before");
args.Proceed();
Console.WriteLine("OnInvoke! after");
}
}
And then decorate methods with [MyAOPThing]. Easy!
.NET Attributes are meta-data, not decorators / active components that automatically get invoked. There is no way to achieve this behaviour.
You could use attributes to implement decorators by putting the decorator code in the Attribute class and call the method with a helper method that invokes the method in the Attribute class using Reflection. But I'm not sure this would be a big improvement over just calling the "decorator-method" directly.
"Decorator-Attribute":
[AttributeUsage(AttributeTargets.Method)]
public class MyDecorator : Attribute
{
public void PerformCall(Action action)
{
// invoke action (or not)
}
}
Method:
[MyDecorator]
void MyMethod()
{
}
Usage:
InvokeWithDecorator(() => MyMethod());
Helper method:
void InvokeWithDecorator(Expression<Func<?>> expression)
{
// complicated stuff to look up attribute using reflection
}
Have a look at frameworks for Aspect Oriented Programming in C#. These may offer what you want.
This type of problem is pretty much what AOP (aspect oriented programming) aims to solve.
Tools such as PostSharp can provide cross-cutting concerns by re-writing the compiled code.
Scott Hanselman's podcast recently discussed AOP, so it might be worth having a listen.
Without the use of code generation, you can't do much against it. You could probably make the syntax better.
But what about using an extension method?
class static MyHelper
{
Wrap<T>(this object service, Action<T> action)
{
// check attribute and wrap call
}
}
usage:
RawFoo foo = ...
foo.Wrap(x => x.doStuffWithData(parameters...));
This is trivial, but you can't make sure that Wrap had been used.
You could implement a generic decorator. This decorator would be used once to wrap the service and then you can't call it without wrapping.
class Decorator<T>
{
private T implementor;
Decorator(T implementor)
{
this.implementor = implementor;
}
void Perform<T>(Action<T> action)
{
// check attribute here to know if wrapping is needed
if (interactsWithData)
{
MyHelper.PerformCall( () => { action(implementor) });
}
else
{
action(implementor);
}
}
}
static class DecoratorExtensions
{
public static Decorator<T> CreateDecorator<T>(T service)
{
return new Decorator<T>(service);
}
}
Usage:
// after wrapping, it can't be used the wrong way anymore.
ExtendedFoo foo = rawFoo.CreateDecorator();
foo.Perform(x => x.doStuffWithData(parameters...));
Check out aspect oriented frameworks. But be aware that while they hide complexity in each method, the existence of AoP features could make your program harder to maintain. It's a tradeoff.
It seems like what you want is similar to behavior of an IoC container or test runner framework, where it isn't actually executing from your assembly, but is running a dynamically emitted assembly built around your code. (Smarter folks than I have called this AOP in other answers)
So maybe in a stub for your app you could scan the other assemblies, build those emitted assemblies (which call MyHelper.PerformCall with the body of the decorated methods) then your program runs against the emitted code.
By no means would I start down the road of trying to write this without evaluating whether some existing AOP framework could accomplish what you need. HTH>
Seeing that you're willing to add a line of code to every method that needs this, why not just make the call to MyHelper from within the method itself, like this?
protected string doStuffWithData(parameters...)
{
MyHelper.PerformCall( () => { doStuffWithDataCore(parameters...) });
}
private string doStuffWithDataCore(parameters...) {
//Do stuff here
}
I have encountered an issue with my new test project when I inherit a razor page from another.
So I had an editor page and I wanted to use the same flow just with gave an extra param (id), the code was:
public class EditModel : BaseModel
{
public EditModel()
{
}
public Task<IActionResult> OnPostAsync(int id)
{
...
}
}
public class CreateModel : EditModel
{
public CreateModel()
{
}
public Task<IActionResult> OnPostAsync()
{
...
}
}
Also I defined the editor cshtml as:
#page "{id:int}"
...
and the create cshtml as:
#page
...
I would expect that the routing was obvious cuz editor's parameter is NOT optional, but create does not need a parameter, but I got the error:
Multiple handlers matched
If I define parameter in create page model too it starts working with 0 value.
I have two questions about that:
Can I define a routing template where I can explicitly forbid the parameter (and how) to avoid ambiguity? (Now I'm using default routing template.)
Shoud I avoid this kind of inheritance of razor pages? I can except that if it is by design and use another way to do it.
I would like to mention that I know I can define another handler methods different from default onget/onpost/etc and use it this way, however I think the above problem should work properly if I can define the routing in a good way.
Hi and welcome to the board! Before digging more about your purposes for this design, let first make something clear about the scenario.
You are probably using ASP.NET Core Razor Page, but you ended up with this line EditModel : BaseModel so I assume that there must be something like BaseModel : PageModel
Next thing I know that you make another inheritance which is CreateModel : EditModel and this time it bugged me out because this obviously will make EditModel inherit a method so-called Task<IActionResult> OnPostAsync(int id) because that what inheritance do!
For example:
public class Test1
{
public void sayHello(){
Console.WriteLine("hehe");
}
}
public class Test2 : Test1
{
public void sayHello(string inputValue){
Console.WriteLine(inputValue);
}
}
and the result when you have something like
Test2 test = new Test2();
test.sayHello();
test.sayHello("something");
The result would be
hehe
something
Once again, I'm not sure about your purposes on this methodology, so it would be nice if you can share some though so we both can evolve in something new.
UPDATE:
At this point, I understand that you created a problem for a case study. So let see if I came up with something right.
.NET core allows you to define some specific route inside Startup.cs beside the default routing, which obviously won't fit in this case.
public void ConfigureServices(IServiceCollection services)
{
services
.AddMvc()
.AddRazorPagesOptions(options =>
{
options.Conventions.AddPageRoute("/edit", "{handler?}/{id?}");
options.Conventions.AddPageRoute("/create", "{handler?}");
});
}
Now, I believe if you put #page "{id:int}" in your .cshtml page, it would run as expected.
I'm using Web API v2 and I have a handful of models that I need to do CRUD operations for. For example, I have an Allergy model and a Prescription model. In the application itself I have viewmodels which can turned into their appropriate models, but for simplicity's sake let's just say I take the model straight in the Web API controller.
So something like this:
public class PrescriptionsController
{
public HttpResponseMessage Put(Prescription model)
{
// saved to the DB
}
... (other CRUD operations)
}
I also have the same for the Allergy model:
public class AllergiesController
{
public HttpResponseMessage Put(Allergy model)
{
// saved to the DB
}
... (other CRUD operations)
}
Both models have different properties but are handled exactly the same way - in fact I have about 3 other models which are handled exactly the same way for each CRUD operation. I hate to do have 5 different endpoints that are basically copied and pasted code.
So my question is this:
Can I make a generic controller to handle all of these models? Something like MyCommonController<T>? (but with a better name of course!) Can the Web API handle the routing in that scenario? Is that even a good idea?
In the end I didn't try a generic controller. It seemed like it might be possible via jumping through some hoops with routing.
However, the fact that routing modifications to get this to work were so complicated it kind of negated the benefit I would get. I wanted to keep things simple. So I just created a generic base class instead:
class MyBaseController<TModel> : ApiController
{
public TModel Get(int id) { ... }
}
and had each type inherit from it:
class PrescriptionsController : MyBaseController<Prescription> { }
And that worked like charm, didn't have to mess with routing or anything. It makes it clear what's happening and is pretty maintainable.
I have a bunch of methods with varying signatures. These methods interact with a fragile data connection, so we often use a helper class to perform retries/reconnects, etc. Like so:
MyHelper.PerformCall( () => { doStuffWithData(parameters...) });
And this works fine, but it can make the code a little cluttery. What I would prefer to do is decorate the methods that interact with the data connection like so:
[InteractsWithData]
protected string doStuffWithData(parameters...)
{
// do stuff...
}
And then essentially, whenever doStuffWithData is called, the body of that method would be passed in as an Action to MyHelper.PerformCall(). How do I do this?
So, I just went to a AOP session this weekend, and here's a way to do it with PostSharp:
[Serializable]
public class MyAOPThing : MethodInterceptionAspect
{
public override void OnInvoke(MethodInterceptionArgs args)
{
Console.WriteLine("OnInvoke! before");
args.Proceed();
Console.WriteLine("OnInvoke! after");
}
}
And then decorate methods with [MyAOPThing]. Easy!
.NET Attributes are meta-data, not decorators / active components that automatically get invoked. There is no way to achieve this behaviour.
You could use attributes to implement decorators by putting the decorator code in the Attribute class and call the method with a helper method that invokes the method in the Attribute class using Reflection. But I'm not sure this would be a big improvement over just calling the "decorator-method" directly.
"Decorator-Attribute":
[AttributeUsage(AttributeTargets.Method)]
public class MyDecorator : Attribute
{
public void PerformCall(Action action)
{
// invoke action (or not)
}
}
Method:
[MyDecorator]
void MyMethod()
{
}
Usage:
InvokeWithDecorator(() => MyMethod());
Helper method:
void InvokeWithDecorator(Expression<Func<?>> expression)
{
// complicated stuff to look up attribute using reflection
}
Have a look at frameworks for Aspect Oriented Programming in C#. These may offer what you want.
This type of problem is pretty much what AOP (aspect oriented programming) aims to solve.
Tools such as PostSharp can provide cross-cutting concerns by re-writing the compiled code.
Scott Hanselman's podcast recently discussed AOP, so it might be worth having a listen.
Without the use of code generation, you can't do much against it. You could probably make the syntax better.
But what about using an extension method?
class static MyHelper
{
Wrap<T>(this object service, Action<T> action)
{
// check attribute and wrap call
}
}
usage:
RawFoo foo = ...
foo.Wrap(x => x.doStuffWithData(parameters...));
This is trivial, but you can't make sure that Wrap had been used.
You could implement a generic decorator. This decorator would be used once to wrap the service and then you can't call it without wrapping.
class Decorator<T>
{
private T implementor;
Decorator(T implementor)
{
this.implementor = implementor;
}
void Perform<T>(Action<T> action)
{
// check attribute here to know if wrapping is needed
if (interactsWithData)
{
MyHelper.PerformCall( () => { action(implementor) });
}
else
{
action(implementor);
}
}
}
static class DecoratorExtensions
{
public static Decorator<T> CreateDecorator<T>(T service)
{
return new Decorator<T>(service);
}
}
Usage:
// after wrapping, it can't be used the wrong way anymore.
ExtendedFoo foo = rawFoo.CreateDecorator();
foo.Perform(x => x.doStuffWithData(parameters...));
Check out aspect oriented frameworks. But be aware that while they hide complexity in each method, the existence of AoP features could make your program harder to maintain. It's a tradeoff.
It seems like what you want is similar to behavior of an IoC container or test runner framework, where it isn't actually executing from your assembly, but is running a dynamically emitted assembly built around your code. (Smarter folks than I have called this AOP in other answers)
So maybe in a stub for your app you could scan the other assemblies, build those emitted assemblies (which call MyHelper.PerformCall with the body of the decorated methods) then your program runs against the emitted code.
By no means would I start down the road of trying to write this without evaluating whether some existing AOP framework could accomplish what you need. HTH>
Seeing that you're willing to add a line of code to every method that needs this, why not just make the call to MyHelper from within the method itself, like this?
protected string doStuffWithData(parameters...)
{
MyHelper.PerformCall( () => { doStuffWithDataCore(parameters...) });
}
private string doStuffWithDataCore(parameters...) {
//Do stuff here
}
What are some cool applications for custom attributes in CLR/C# code that you've done or heard about? Also interesting new uses of the standard attributes is also ok!
Edit: Since Java's annotations seems to be the same as CLR's attrbutes, uses of Java annotations is also valid.
postsharp, which uses attributes to inject code (AOP)?
[TypeDescriptionProvider] which can be used to provide a custom runtime property model - either completely different properties, or perhaps faster ones
And some core ones that are often overlooked:
[TypeForwardedTo] - used to move types between assemblies without re-building
[PrincipalPermission] - used to automatically enforce security on members
While not strictly C#, I've found an interesting use of Java annotations (= C# attributes) for marking student's assignments. Every semester I program a marking robot for students, and it turns out that first-year students for some reason don't seem to be able to follow instructions precisely, which of course causes the marking robot to fail. So what I do is go through their code, find all the methods that didn't meet the specification and fix them. Then I put an annotation (=attribute) onto each of the methods that were wrong, telling the marking robot to mark them down. It's probably the most simple and direct way to do this I think.
Check out xUnit and see how attributes are used to mark unit tests for expected behavior as well as feed data into tests. Attributes are used in a more meaningful manner than MSTest or NUnit.
From Samples\TestMethodExtensibility\Example.cs:
public class Example
{
static int val;
[RepeatTest(5, Timeout=250)]
public void RepeatingTestMethod()
{
Thread.Sleep(100);
Assert.Equal(2, 2);
if (val == 0)
{
val++;
Thread.Sleep(1000);
}
}
}
From test.xunit.extensions\DataTheories\TheoryAttributeTests.cs:
internal class TestMethodCommandClass
{
public static IEnumerable<object[]> EmptyData
{
get { return new object[0][]; }
}
public static IEnumerable<object[]> NullData
{
get { return null; }
}
public static IEnumerable<object[]> TheoryDataProperty
{
get { yield return new object[] { 2 }; }
}
[Theory, PropertyData("EmptyData")]
public void EmptyDataTheory() { }
[Theory, PropertyData("NullData")]
public void NullDataTheory() { }
[Theory, OleDbData(
#"Provider=Microsoft.Jet.OleDb.4.0; Data Source=DataTheories\UnitTestData.xls; Extended Properties=Excel 8.0",
"SELECT x, y, z FROM Data")]
public void TestViaOleDb(double x,
string y,
string z) { }
[Theory, PropertyData("TheoryDataProperty")]
public void TestViaProperty(int x) { }
[Theory, ExcelData(#"DataTheories\UnitTestData.xls", "SELECT x, y, z FROM Data")]
public void TestViaXls(double x,
string y,
string z) { }
}
For details see:
http://www.codeplex.com/xunit
nunit of course
the usages of attributes has been prided by kent beck:
NUnit 2.0 is an excellent example of idiomatic design. Most folks who port xUnit just transliterate the Smalltalk or Java version. That's what we did with NUnit at first, too. This new version is NUnit as it would have been done had it been done in C# to begin with.
source: http://www.nunit.org/
I have a case, where I want to present the actual implementation of an interface as data as well. This can be done via Reflection of course, but by using a specific attribute on the members I want to expose as data, I can encapsulate the work needed to do this.
The end result is that I create my implementation, decorate the desired members and then I can query the members through both code and data without having to do the Reflection code in each case.
Sometimes, I use attributes to decorate classes or methods and use reflection to get the 'attributed' data.
Maybe a bit difficult to explain, but the last thing for which I've used attributes, is in a system where I have a couple of entities in a database.
Each entity has some kind of 'code', and each entity can also have some interpretation rules.
In my project, I have one entity class, which represents an entity that exists in the Database, and, I also have a set of 'Rule' classes.
One Rule class contains the interpretation logic of a given entity.
In order to 'link' a certain 'Rule' (interpretation) to a specific instance of my entity, I've created a custom Attribute.
I decorate my 'Rule' class with this attribute, and through the attribute, I define for which entity this is a Rule.
Then, when I load an entity from the DB, I inject the correct rule into that entity.
A little bit of code to make things clear:
public class MyEntity
{
public string Code
{
get;
private set;
}
public bool IsValidFor( ... )
{
IRule rule = RuleRegistry.GetRuleFor(this);
if( rule.IsValid() ) ...
}
}
[RuleAttrib("100")]
public class MyRule : IRule
{
public bool IsValid()
{
}
}
This is just a little example, but I think you'll catch the drift.
The RuleAttrib attribute on the MyRule class, says that this is a Rule that should be applied to the instance of MyClass which has a code "100".
The RuleRegistry instance is able to retrieve the correct IRule for the current Entity (using reflection).
Another example in where I've used attributes, in combination with Postsharp, is the implementation of a 'locking' system:
http://fgheysels.blogspot.com/2008/08/locking-system-with-aspect-oriented.html
we use custom java annotations to mark special purposes of certain methods, mostly targeted at developers:
#ScriptingAPI -- marks code that is exposed as part of our scripting API (warns developers that changes could affect the public API)
#Transaction -- marks methods on the database facade that are starting/commiting a transaction (we have a dedicated transaction handler class that respects this annotation)
#NeedsAttentionToSupportFoo -- if we know that feature Foo is a requirement that we will need to address in the near future, we use an annotation to mark code that we will need to touch to support it, i.e. when we come across a piece of code that makes us think "ah, this will need to be changed to support Foo", we annotate it. if the implementation of Foo is postponed or will never happen, it's easier to remove the annotation than to revert pre-mature optimizations scattered all around in the code.
another good example usage of a custom annotation is covered in this java specialist newsletter: enforcing a public no-args constructor in all sub classes.
Castle's ActiveRecord uses attributes. It hides some of the set-up complexity of NHibernate by decorating your Model objects with attributes indicating classes and fields that should be persisted to the database (and how). There is also use of attributes within the validation component to add model-based validation into ActiveRecord and the Monorail stack.