I want to facade or proxy a library's implemented attribute.
for example the property mapping attributes.
I want to control which of the libraries attributes to be used in project.
some kind of a DI or Module control.
Is there an easy way to achieve it without using reflection?
something to transfer these two types of attributes into one:
[MapsFromAndToProperty(typeof(fooClass), nameof(fooClass.PropertyName))]
and
[AdaptMember(name)]
into
[MyAttributeToControlWhichOneToUse(typeof(fooClass), nameof(fooClass.PropertyName))]
And Thank you for your attention.
Any help would be appreciated.
As noted in the comments, it is not possible to alter attributes in the general case. This is simply because attributes are effectively part of the assembly metadata and doing what you want means to change that assembly metadata.
There are two ways how this could potentially work, though:
You do change the assembly metadata. Here, you are in the realm of aspect-oriented programming. You could try to create an aspect e.g. based on PostSharp that unrolls your MyAttributeToControlWhichOneToUse attribute into the required attributes at compile-time. This solution is independent of the way how the attributs are read, but requires changes to the build infrastructure.
You alter the way how the attributes are loaded. MEF is an example that does that for its convention-based programming model that effectively emulates attributes on the conventional classes by altering the way how attributes are retrieved. This only works, if foreseen in the lib that reads the properties (and honestly, I have never seen anybody else than MEF to do that).
Related
I'm trying to create a generic layer between the frameworks I am using and my application's code and have been blocked by a framework's need to decorate my classes with attributes.
Is there a way to be able to somehow map attributes to other attributes?
Example:
Class A is decorated with Attribute B
At runtime, map Attribute B to Attribute A
Class A is seen as decorated by Attribute A throughout the application's life.
What you are trying to do sounds like bad design. Attributes are not runtime types, they are in fact just type metadata. Even though some attributes allow you to change their parameters at runtime, that will not change which attribute is applied.
You will find solutions on the internet that suggest using Reflection.Emit. Note that this is a slippery slope and will lead to highly unmaintainable code.
My personal suggestion would be to create your own Class B that is decorated with both Attribute A as well as Attribute B, and then use internal logic to bridge whatever it is that you are wanting to bridge.
Could anyone explain the benefits (or reasons) to use custom attributes in your code. Of course I use (and understand the purpose of) defined attributes in certain scenarios (WCF, Serialization etc.), but I cannot imagine any algorithms where I would need to create and use my own custom attributes. Could someone provide a real-world case where usages of custom defined attributes bring something to a project.
The same reason as for WCF etc, but something that's specific to your project - you want to add some metadata to some members (types, fields, methods, whatever) to specify something about the mechanism involved, and it's not something which is covered by existing attributes.
For example, NUnit wanted to add their own indication that a particular type contained unit tests - there was no such existing attribute, so they created TestFixtureAttribute.
It's a relatively rare event, sure - but it can happen.
If you want to write your own system like WCF, Serialization, etc...
If you write code that iterates over types or members and does things with them, you will frequently want to use your own custom attributes to mark some members as being different or special.
I regularly use custom .Net attributes to support tooling in my infrastructure. One example was from very early in the .Net days (C# 1.0 to be exact). I was working on a research project which had a native C++ front and a brand new C# back end written by yours truly.
The front and back end shared a very similar object model which was evolving very rapidly. Not wanting to have to hand code both a C++ front end model, C++ serialization mechanism and a C# serialization mechanism I chose instead to attribute my C# types with custom attributes. They told me the parts of the model which were shared between the front and back end.
Once those attributes were in place I wrote a quick and dirty tool which
Parsed out the attributes to construct the core shared model
Generated the C# serialization code
Generated the C++ code
Generated the C++ serialization code
This made it dirt simple to keep my model up to date between my 2 projects. Just change the C# code, compile and re-run my tool.
I have used annotations in a custom AOP (Aspect-Oriented Programming) system I developed a while back. Attributes are also very useful for controlling orthogonal concerns like code generation.
Custom validation is a very good use case and can be seen from these links:
http://odetocode.com/blogs/scott/archive/2011/02/21/custom-data-annotation-validator-part-i-server-code.aspx
How to create Custom Data Annotation Validators
They can be used for marking tests, as in MBUnit for example. They can also be useful for code that inspects and loads classes (like a Plugin system) to provide meta-information.
They are really useful in building object mappers / ORM tools as well. If you ever decide to roll your own mapping system they are almost "required" to get all the functionality one would need. It's used more for making methods / classes more generic and using reflection to determine how to handle objects / select objects /etc...
To give you a specific case where I've used them. I once had to interact with a Mainframe screenscraper. I created a custom attribute to annotate which fields I wanted to send from my classes to the Mainframe, names that fell outside of conventions, special rules to deal with formatting and collections. I then had a class which was able to reflect over instances and realise which subset of fields were needed to interact with the mainframe screen scraper appropriately.
I want to point to a directory of DLL's and read the attributes of the classes in it. Most classes have a custom attribute with various properties that I want to read.
I have some old code which uses Assembly.GetCustomAttributes
Is this still considered the best approach?
Assembly.GetCustomAttributes gets you attributes for the assembly - which is assemblie's metadata. This are usually place in the AssemblyInfo.cs while they can be placed anywhere.
It should not be confused with class custom attributes - or property/method/field/etc.
If you mean you want to filter out assemblies to look out for by having a custom attribute which identifies such assemblies of interest, then it is a valid approach. However, bear in mind, to read such attributes, assembly first needs to be loaded onto memory.
Reflection is the only way to read custom attributes. Some pseudo custom attributes are reflected on properties of the System.Type class. Assemblies loaded 'normally' cannot be unloaded from an appdomain, so ideally you want to load the assemblies into a reflection only context (there are methods System.Reflection.Assembly.ReflectionOnlyLoad and ReflectionOnlyLoadFrom) so that they may be unloaded when you have your desired information.
I have the idea that it might be useful to enforce type visibility between namespaces rather than assemblies (internal) in C#.
It would seem that such a concept would assist developers working with a codebase, ensuring the correct types are used in places where another internal type supplying similar functionality is available, but would result in "architectural" disadvantages (unwanted dependencies etc).
Do others think this would be useful and is it currently possible? If not why not?
Also, would the concept of preclusions - the ability to specify negative constraints on references between namespaces and / or assemblies be a useful addition to C#?
A type is strongly bound to the assembly in which it is defined. A namespace is not, it can appear in multiple assemblies. System.Configuration for example.
Let's assume for a moment that the metadata format for an assembly would be changed (-1 billion points) to store attributes for a namespace. Those attributes would still have to be stored in an assembly because that's the storage unit for metadata. Now you have to deal with the possibility that the CLR loads another assembly and finds the same namespace but with conflicting attributes. How could it possibly resolve that?
More seriously, how would you prevent external code from simply using the same namespace and attributes to suddenly get access to implementation details that were meant to be private. This completely destroys the value of having the internal keyword.
You could make them public, tag them with a custom attribute, and then add a FxCop rule to check for accesses from the outside of the namespace.
This doesn't securely enforce the restriction and fails when the member is accessed with reflection, but if it's only about policy/codingstyle this should be enough.
I think there is also an existing attribute to hide members from Intellisense which you might use in conjunction with your custom attribute.
I'm writing some library code, and classes that use that code are required to have two attributes specified (one custom attribute and one from .NET).
It's a bit of a hassle to document this requirement and copy-and-paste both of those attributes onto every class that uses my library, so I thought it might be better to have my custom attribute just imply the presence of the other. That other attribute from the .NET framework is sealed, though, so I can't just inherit it...
So is there any way to do this? Can I maybe add the .NET attribute at runtime?
Thanks.
Whilst you can use inheritance in attributes it is recommended you don't.
Since this is only a performance rule you will not violate correctness but it can be a source of some confusion and you must spend a great deal of effort to ensure you do not violate the semantics of the base attribute. You may cause issues if you attempt to expand the possible locations for the attribute with the AttributeUsage flags. The rules for the attribute in question are quite complex.
A method can have either of the two attributes applied, but not both. Any operation that has neither applied uses the attribute applied to the containing class. If the containing class does not have either attribute applied, the DataContractSerializer is used.
Give this making it sealed sounds like a sensible plan on their part. This API is not designed with this sort of extension in mind.
There is no way (short of AOP style 'code injection') to add attributes to existing classes at runtime.
I do not believe there is a way to imply secondary attributes or to add attributes at runtime. However, you could use a custom code template to add the attributes to every class as you add them. And/or for classes that are already developed, I suspect you could write a macro that goes through each file and adds the attributes to the classes, however I have not done this in the past, so I'm not sure what it would entail, I know making a code template to add to attributes to a class declaration is relatively simple. But this only works for class you're adding from the point of template addition on. If you need to do cleanup to old classes as well, I would look into macros if you have a lot of files/classes this needs to be done for. Or do it manually if there are not too many.