FWIW: When I come across reflection code it's often a smell, especially when written by a novice developer. Quite often there's a much simpler (and less fragile) way to do something. Reflection is a powerful technique with many gotchas; and the gotchas can quickly outweigh the benefits.
I try to avoid using custom attributes to configure things like business logic because they struggle to account for interactions between members. Attributes have no affordance for lambdas, delegates, method references, etc. You would need a separate piece of logic that interprets the primitive attribute data in order to provide any emergent properties between members.
A better approach is often to expose some abstract/interface member that allows for the implementation to define its logic using something like a fluent-style contract. In this arrangement you can pass the type itself as an argument to a lambda making it trivial to define logic that should execute over many members at once. Debugging this also tends to be more pleasant. AspNetCore startup code, LINQ and EF are good examples.
Attributes are useful for things that are definitely pure data and only when the information fully belongs to the thing being annotated regardless of context of use. The moment some kind of per-member custom logic is needed it's no longer appropriate. I think things like [Authorize] are borderline. [JsonIgnore] seems like a good attribute to me.
This is my experience too, I've worked on code bases which made heavy use of attributes, and they work really well to provide static per-type information, but if you see them as a universal problem solver and try to go too fancy, you'll find yourself in trouble.
Fluent builders are nicer to work with than attributes, although it sometimes feels weird if the defaults are nearly fine but not quite, and you wish you could just reach for a single attribute rather than having to traverse down 3 layers of builders to change a single property.
The only case I've used them was to mark classes that I need to find via reflection and do something with them. For example a migration system where you want to load all migrations that are defined and check if you need to run them. Of course you don't really need an attribute for that, but I find it helpful to leaven a marker on the class that there's something else going on there.
FWIW, Custom Attributes in .Net are kind of a pain in geneal, powerful but painful
Why? What's kind of painful in general about them? They are just pieces of static data. You can abuse them, e.g. have some obscure logic somewhere, but you can abuse many things just the same (ahem, Reflection, excuse me), so this factor doesn't make a distinction.
Probably why JS still doesnt really have them in practice.
Did you mean JS doesn't have TS decorators? Those are an entirely different beast.
FWIW: When I come across reflection code it's often a smell, especially when written by a novice developer. Quite often there's a much simpler (and less fragile) way to do something. Reflection is a powerful technique with many gotchas; and the gotchas can quickly outweigh the benefits.
I try to avoid using custom attributes to configure things like business logic because they struggle to account for interactions between members. Attributes have no affordance for lambdas, delegates, method references, etc. You would need a separate piece of logic that interprets the primitive attribute data in order to provide any emergent properties between members.
A better approach is often to expose some abstract/interface member that allows for the implementation to define its logic using something like a fluent-style contract. In this arrangement you can pass the type itself as an argument to a lambda making it trivial to define logic that should execute over many members at once. Debugging this also tends to be more pleasant. AspNetCore startup code, LINQ and EF are good examples.
Attributes are useful for things that are definitely pure data and only when the information fully belongs to the thing being annotated regardless of context of use. The moment some kind of per-member custom logic is needed it's no longer appropriate. I think things like [Authorize] are borderline. [JsonIgnore] seems like a good attribute to me.
This is my experience too, I've worked on code bases which made heavy use of attributes, and they work really well to provide static per-type information, but if you see them as a universal problem solver and try to go too fancy, you'll find yourself in trouble.
Fluent builders are nicer to work with than attributes, although it sometimes feels weird if the defaults are nearly fine but not quite, and you wish you could just reach for a single attribute rather than having to traverse down 3 layers of builders to change a single property.
The only case I've used them was to mark classes that I need to find via reflection and do something with them. For example a migration system where you want to load all migrations that are defined and check if you need to run them. Of course you don't really need an attribute for that, but I find it helpful to leaven a marker on the class that there's something else going on there.
> My guess is that Microsoft just does not think it is worth creating an update (especially since attributes usually do not affect runtime behavior).
I wonder if this is why dotnet's startup time is so long? Might be worth revising just to get assembly resolution time down.
.. if you're trying to parse the assemblies by hand for some reason. If you're just trying to handle them with reflection none of this is an issue.
> If you're just trying to handle them with reflection none of this is an issue
But maybe indicates on how expensive that reflection call can be? Reading multiple .dlls ?
FWIW, Custom Attributes in .Net are kind of a pain in geneal, powerful but painfull... Probably why JS still doesnt really have them in practice.
haha, "use server", use...(use...(...))