Why Custom Attributes in .NET Give Me Nightmares
blog.washi.dev
Why Custom Attributes in .NET Give Me Nightmares
1–10 of 30 posts
Re: Why Custom Attributes in .NET Give Me Nightmares
#2Re: Why Custom Attributes in .NET Give Me Nightmares
#3.. 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.
But maybe indicates on how expensive that reflection call can be? Reading multiple .dlls ?
Re: Why Custom Attributes in .NET Give Me Nightmares
#4.. 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 ?
That also necessarily has the parser for all the "System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" machinery.
>> "While C# does not support types with weird symbols, it is possible to have type names with spaces, commas, brackets, unprintable characters, and more. This is also heavily (ab)used by code obfuscators."
.. hmm. I didn't know that.
I will note that there is a milder version of this problem which you might encounter if you're trying to write a dotnet source generator, which is run inside the Roslyn compiler. You then need to remember that the types in the code being compiled are not directly visible from reflection, you have to ask the compiler to look them up for you in the parsed data.
These cases are easy:
- types in the netstandard2.0 standard library
- types in the assembly currently being compiled
This case is not: - types in assemblies in the same project which the current assembly depends on
I ended up avoiding handling that at all. It does set some limits on what is easily done with source generators.(by the way, someone sufficiently dedicated should be able to find the corresponding Microsoft loader code: it's all in the dotnet github)
Re: Why Custom Attributes in .NET Give Me Nightmares
#5A 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.
Re: Why Custom Attributes in .NET Give Me Nightmares
#6I 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 abstrac…
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.
Re: Why Custom Attributes in .NET Give Me Nightmares
#7.. 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 ?
Re: Why Custom Attributes in .NET Give Me Nightmares
#8I 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 abstrac…
Re: Why Custom Attributes in .NET Give Me Nightmares
#9Re: Why Custom Attributes in .NET Give Me Nightmares
#10I 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 abstrac…
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.