Is there any way to change a class' attributes? - c#

I am using Microsoft REST Stark Kit Preview 2 to explore REST Collection WCF Service. Within the Service.svc.cs class, there are some classes and interfaces being used as base or component classes. For example:
public interface ICollectionService<TItem> where TItem : class
{
...
[WebHelp(Comment = "Returns the items in the collection in JSON format, along with URI links to each item.")]
[WebGet(UriTemplate = "?format=json", ResponseFormat = WebMessageFormat.Json)]
ItemInfoList<TItem> GetItemsInJoson();
...
}
[CollectionDataContract(Name = "ItemInfoList", Namespace = "")]
public class ItemInfoList<TItem> : List<ItemInfo<TItem>> where TItem : class
...
where ICollectionServices and ItemInfoList are all in Microsoft.ServiceModel.Web.dll in the Preview 2. I would change those item's attributes such as WebHelp's Comment and CollectionDataContract's Name so that I could customize help message and templates for xml node names. The Preview 2's change with embedding those interfaces and classes in its dll makes it difficult to do any customization.
So my question is that if there is any way to change a class or interface's attributes or overwrite their existing attributes so that I don't need to get the source codes to make changes?

No, you can't.
What you might be able to do is inherit from the classes. If the attributes in question are not inheritable, you can add your own to your subclasses to override them.
I checked the CollectionDataContractAttribute, and it, at least, is not inheritable. That means if you create a subclass, you can apply a different CollectionDataContract attribute to that subclass.
[CollectionDataContract(Name = "MyItemInfoList", Namespace = "MyNamespace")]
public class MyItemInfoList<TItem> : ItemInfoList<TItem> where TItem : class
However, with members, this approach will only work if they are virtual, so you can override them.

Attributes are burnt in at compile time, and cannot for reflection be set at runtime. There are a few things you can do in "ComponentModel", but they wouldn't apply here. The only other common case here is for "i18n", where an attribute might be designed to pick up different values at runtime (from resx etc, based on a key rather than the description being set in the code) - and again, this doesn't apply in this case.
So, no.

In terms of REST Start kit Preview 2's customization issue, it look like the customization was disabled when the template basic classes are moved to its core dll. According to WCF REST Start kit forum at ASP.NET, the customization features will be back in the next release (soon).

Related

Statically defining options for a type of a derived class

I'm developing a framework where a class inheriting from an abstract class of the framework needs to be able to specify the schema for the options it can accept when it is called to DoStuff().
I started out with an abstract GetOptionsSchema() method like this:
public abstract class Widget
{
public abstract OptionsSchema GetOptionsSchema();
public abstract void DoStuff(Options options);
}
Other developers would then extend on my framework by creating custom Widget types:
public abstract class FooWidget: Widget
{
public overide DoStuff(Options options)
{
//Do some FooWidget stuff
}
public overide OptionsSchema GetOptionsSchema()
{
//Return options for FooWidget
}
}
This works but requires the framework to create an instance of every Widget type to determine options schema they accept, even if it has no need to actually DoStuff() with any of these types.
Ultimately, I'd like to be able to determine the options schema for a specific Widget type directly from a System.Type. I would create a custom OptionsSchema attribute, but constructing these schemas is more complicated then would make sense to do in the constructor of an attribute. It needs to happen in a method.
I've seen other frameworks solve similar problems by creating a custom attribute that identifies a static method or property by name. For example the TestCaseSource attribute in NUnit.
Here's what this option might look like:
public abstract class Widget
{
public abstract void DoStuff(Options options);
}
[OptionsSchemaSource(nameof(GetOptionsSchema))]
public abstract class FooWidget: Widget
{
public overide DoStuff(Options options)
{
//Do some FooWidget stuff
}
public static OptionSchema GetOptionsSchema()
{
//Return options for FooWidget
}
}
I like how the OptionsSchemaSource attribute makes it possible to get the options schema directly from a System.Type, but this also seem much less discoverable to other developers creating custom Widget types.
With the abstract method another Widget developer knows they must override GetOptionSchema() because their code would not compile otherwise. With the OptionsSchemaSource attribute the best I could do would be to hope people read my documentation and have the framework throw an exception at run-time if it encounters a Widget with out an OptionsSchemaSource attribute.
Is there an alternative/better/recommended approach to this?
You pretty much already know everything of interest to judge what's the best approach.
As already mentioned, you cannot have static interfaces defined on your type, so there is no way you can ensure a new developer is enforced to add the attribute.
So, the two alternatives you identified are the only two I can think of.
Now, let's do a pros and cons and try to sharpen them.
Attribute
You can lessen the pain of ensuring devs put attributes on the classes with meaningful error messages. I would say that you should manage the discovery of the classes based exclusively on Attributes, not in inheritance.
If you manage everything with Attributes, you don't need to inherit from Widget.
This is a pro, because now everyone can inherit if it's desirable, and re-implement if it's preferred.
The con is that the implementation of discoverability will be more complex: you will need to use reflection at start up, get a MethodInfo, check that the method has the correct signature, give proper errors in case and invoke the method unboxing the result as needed.
Think about it: you would like a static method because you don't need to instantiate a single typed Widget instance, but actually instantiating a new Widget could very well be not a big deal.
Abstract class
Well, you enforce an inheritance chain over you developers, which could be ok, necessary or entirely optional (you judge), but you get a self documenting experience.
The apparent con is that at startup you need to instantiate a Widget for every derived type you discover, but that could very well be peanuts compared to assembly scanning and type checking and methodinfo discovery and method calls through reflection.
Ugly? Kind of. Inefficient? Not so much. And it's code that is invisible to your end user.
IMHO
I find quite a good tradeoff, when designing a framework, to put some "ugly" code inside the framework, if it means that every single implementation using the library is going to be even a little bit better.
All in all, if you're designing a library that you want to be flexible and discoverable, you should expect a developer to read at least a quick start guide. If they can read in 5 minutes a single bit of information (either "extend a base class" or "add a single or a couple attributes") and that single bit gives them an direction into discovering every aspect of widget registration, I would be ok: you can't really get much better than this.
My call: I would go the abstract class route with a smallish caveat. I really don't like having an enforced base class. So I would organize discovery at startup based on interface, IWidget, containing the GetOptionsSchema method and everything is needed to use the widget (which could be the DoStuff method, but could very well be something else). At startup you search for implementations of the interface which are not abstract, and you're good to go.
If, and only if, the only bit you really need in advance is a string or other similarly simple type, I would require an additional attribute.
[OptionsSchemaName("http://something")]
public class MyWidget : WidgetBase
{
public overide DoStuff(Options options)
{
//Do some FooWidget stuff
}
public static OptionSchema GetOptionsSchema()
{
//Return options for FooWidget
}
}
Then, your type discovery infrastructure can search for non-abstract IWidgets and throw a meaningful error right at startup like the type MyWidget is lacking an OptionsSchemaName attribute. Every implementation of IWidget must define one. See http://mydocs for information.
Bang! Nailed it!
It's not currently possible to enforce the attribute at compile time; that would've been ideal for your use case. It's also not possible to have an abstract static method, or have a static method specified in an interface; so there is no way to ensure the method is actually there at compile time, except by enforcing an instance method via abstract class or interface (which will require an instance of the type to access).
I'd go with the attribute idea - it's not unreasonable to expect developers to read documentation; even with overriding an abstract method, the developer would need to know how to construct an OptionSchema in the overridden method - back to documentation!

C# UML Class diagram

I'm writing a class diagram for my project, but unsure whether or not I should be including my overridden ToString() method on the diagram?
Also, how do I represent overridden methods on the diagram?
For example...
public override String SalesPrice()
Usually you wouldn't really need to include any extra details on the UML class diagram that the method is 'Overriden' or 'Virtual' Etc,
But if you wish to do so, I was told that it should be represented in the same way as abstract classes (Italic writting) / use of 'Arrows' either side like so..
<<Override>>
<<Virtual>>
So to comply with your example:
+ SalesPrice (): <<Override>> : String
and within your superclass you will need to specify as follows:
+ SalesPrice (): <Virtual>> : String
okay so I finally found the book I mentioned (I am moving soon so it was packed).
in UML Inheritance is called generalization and it simply shows 2 boxes one pointing to the other no attributes.
I would assume that since you have defined the method in a base class that you would not have to in classes that inherit from it.
however there is a place that states that operations are defined as:
"visibility name ( parameters ) : return-type {properties}"
and for properties:
"properties
Specifies any parameters-related properties and is specified between curly braces. These are typically defined within the context of a specific model"
although the properties seem more for the parameters than the actual method but you may be able to fudge this a little
now for interfaces:
under the interfaces section it states explicitly that the class that "realizes" the interface must have it's own implementation. so in short I would add any overridden methods to the class diagram. otherwise whom ever implements your diagram might not realize that they need to override it.
I am using uml 2.0 in a nut shell as my reference. pg's 20,28,30

How to find out which interfaces a .net class implements?

Ok, so I've been learning c# and .net recently and one thing that seems to be missing from the c# documentation on http://msdn.microsoft.com/ that is present in the java documentation (e.g. ArrayList doc) is that a java class's documentation will say something like:
All Implemented Interfaces: Serializable, Cloneable, Iterable,
Collection, List, RandomAccess Direct Known Subclasses:
AttributeList, RoleList, RoleUnresolvedList
This allows me to find out which interfaces it implements and possibly discover interfaces I didn't know of yet. I can further click on an interface and get information on which classes implement it (in the standard classes anyway) and which interfaces extend it:
All Superinterfaces:
Iterable<E>
All Known Subinterfaces:
BeanContext, BeanContextServices, BlockingDeque<E>, BlockingQueue<E>, ...
All Known Implementing Classes:
AbstractCollection, AbstractList, AbstractQueue, AbstractSequentialList, ...
When using Microsoft's documentation I only get the base classes and possibly subclasses:
System.Object
System.MarshalByRefObject
System.IO.Stream
More...
"More..." being a link with a list of subclasses.
Is there a way in the documentation to find what interfaces a .Net class implements in a similar way that we can in the Java documentation?
Edit: I'm using Visual Studio Express and the publicly available documentation on MSDN so I suppose that the answer might be: yes you can, but you must pay up first for [full visual studio|MSDN subscription|...].
Documentation
Check out the Syntax section (e.g. for IObservableCollection(T)) in the documentation.
This gives the class declaration, including implemented interfaces
[SerializableAttribute]
public class ObservableCollection<T> : Collection<T>,
INotifyCollectionChanged, INotifyPropertyChanged
ILSpy
However, for classes for which documentation is not available, you can use a dissassembler such as ILSpy. Simply select a class, and it will show all base-types and derived types.
Object Browser
Finally, you can also use the Object Browser in Visual Studio (I'm not 100% sure it's in Express). View → Object Browser. This will show the base-types as you require.
In Visual Studio, place the caret on the thing you want to know about e.g. bool and press F12
It will show you the definition of the thing you pressed F12 on, so for bool:
namespace System
{
// Summary:
// Represents a Boolean value.
[Serializable]
[ComVisible(true)]
public struct Boolean : IComparable, IConvertible, IComparable<bool>, IEquatable<bool>
{
// Summary:
// Represents the Boolean value false as a string. This field is read-only.
public static readonly string FalseString;
...
Additionally you can open the Code Definition Window (View>Code Definition Window, Ctrl+W,D) which will show the above in a window - no button presses needed!
Resharper has a feature that allows that as well. If you press Ctrl+Shift+F1 then you can see a documentation about the class with full list of interfaces that it implements. You can decompile it using resharper to achieve the same result (though it's a little bit too much for what you need).
Resharper has Go to Base Symbols. you can use:
CTRL + U
Right click the class name > Navigate > Base Symbols
Resharper menu > Navigate > Base Symbols
This command allows you to navigate up the inheritance hierarchy to a
base type [including classes and interfaces] or method of the current symbol.
Here's a sample from a XAML.cs file

How do attribute classes work?

My searches keep turning up only guides explaining how to use and apply attributes to a class. I want to learn how to create my own attribute classes and the mechanics of how they work.
How are attribute classes instantiated? Are they instantiated when the class they are applied to is instantiated? Is one instantiated for each class instantiated that it is applied to? E.g. if I apply the SerializableAttribute class to a MyData class, and I instantiate 5 MyData instances, will there be 5 instances of the SerializbleAttribute class created behind the scenes? Or is there just one instance shared between all of them?
How do attribute class instances access the class they are associated with? How does a SerializableAttribute class access the class it is applied to so that it can serialize it's data? Does it have some sort of SerializableAttribute.ThisIsTheInstanceIAmAppliedTo property? :) Or does it work in the reverse direction that whenever I serialize something, the Serialize function I pass the MyClass instance to will reflectively go through the Attributes and find the SerialiableAttribute instance?
I haven't use attributes in my day-to-day work before, but I have read about them.
Also I have done some tests, to back up what I'll say here. If I'm wrong in any place - feel free to tell me this :)
From what I know, attributes are not acting as regular classes. They aren't instantiated when you create an object that they are applied to, not one static instance, not 1 per each instance of the object.
Neither do they access the class that they are applied to..
Instead they act like properties (attributes? :P ) of the class. Not like the .NET class properties, more like in the "one property of glass is transparency" kind of property. You can check which attributes are applied to a class from reflection, and then act on it accordingly. They are essentially metadata that is attached to the class definition, not the objects of that type.
You can try to get the list of attributes on a class, method, property, etc etc.. When you get the list of these attributes - this is where they will be instantiated. Then you can act on the data within these attributes.
E.g. the Linq tables, properties have attributes on them that define which table/column they refer to. But these classes don't use these attributes. Instead, the DataContext will check the attributes of these objects when it will convert linq expression trees to SQL code.
Now for some real examples.. I've ran these in LinqPad, so don't worry about the strange Dump() method. I've replaced it with Console.WriteLine to make the code easier to understand for the people who don't know about it :)
void Main()
{
Console.WriteLine("before class constructor");
var test = new TestClass();
Console.WriteLine("after class constructor");
var attrs = Attribute.GetCustomAttributes(test.GetType()).Dump();
foreach(var attr in attrs)
if (attr is TestClassAttribute)
Console.WriteLine(attr.ToString());
}
public class TestClassAttribute : Attribute
{
public TestClassAttribute()
{
DefaultDescription = "hello";
Console.WriteLine("I am here. I'm the attribute constructor!");
}
public String CustomDescription {get;set;}
public String DefaultDescription{get;set;}
public override String ToString()
{
return String.Format("Custom: {0}; Default: {1}", CustomDescription, DefaultDescription);
}
}
[Serializable]
[TestClass(CustomDescription="custm")]
public class TestClass
{
public int Foo {get;set;}
}
The console result of this method is:
before class constructor
after class constructor
I am here. I'm the attribute constructor!
Custom: custm; Default: hello
And the Attribute.GetCustomAttributes(test.GetType()) returns this array:
(the table shows all available columns for all entries.. So no, the Serializable attribute does not have these properties :) )
Got any more questions? Feel free to ask!
UPD:
I've seen you ask a question: why use them?
As an example I'll tell you about the XML-RPC.NET library.
You create your XML-RPC service class, with methods that will represent the xml-rpc methods. The main thing right now is: in XmlRpc the method names can have some special characters, like dots. So, you can have a flexlabs.ProcessTask() xml rpc method.
You would define this class as follows:
[XmlRpcMethod("flexlabs.ProcessTask")]
public int ProcessTask_MyCustomName_BecauseILikeIt();
This allows me to name the method in the way I like it, while still using the public name as it has to be.
Attributes are essentially meta data that can be attached to various pieces of your code. This meta data can then be interogate and affect the behaviour of certain opperations.
Attributes can be applied to almost every aspect of your code. For example, attributes can be associated at the Assembly level, like the AssemblyVersion and AssemblyFileVersion attributes, which govern the version numbers associated with the assembly.
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
Then the Serializable attribute for example can be applied to a type declaration to flag the type as supporting serialization. In fact this attribute has special meaning within the CLR and is actually stored as a special directive directly on the type in the IL, this is optimized to be stored as a bit flag which can be processed much more efficiently, there are a few attributes on this nature, which are known as pseudo custom attributes.
Still other attributes can be applied to methods, properties, fields, enums, return values etc. You can get an idea of the possible targets an attribute can be applied to by looking at this link
http://msdn.microsoft.com/en-us/library/system.attributetargets(VS.90).aspx
Further to this, you can define your own custom attributes which can then be applied to the applicable targets that your attributes are intended for. Then at runtime your code could reflect on the values contained in the custom attributes and take appropriate actions.
For a rather naive example, and this is just for the sake of example :)
You might want to write a persistence engine that will automatically map Classes to tables in your database and map the properties of the Class to table columns. You could start with defining two custom attributes
TableMappingAttribute
ColumnMappingAttribute
Which you can then apply to your classes, as an example we have a Person class
[TableMapping("People")]
public class Person
{
[ColumnMapping("fname")]
public string FirstName {get; set;}
[ColumnMapping("lname")]
public string LastName {get; set;}
}
When this compiles, other than the fact that the compiler emits the additional meta data defined by the custom attributes, little else is impacted. However you can now write a PersistanceManager that can dynamically inspect the attributes of an instance of the Person class and insert the data into the People table, mapping the data in the FirstName property to the fname column and the LastName property to the lname column.
As to your question regarding the instances of the attributes, the instance of the attribute is not created for each instance of your Class. All instances of People will share the same instance of the TableMappingAttribute and ColumnMappingAttributes. In fact, the attribute instances are only created when you actually query for the attributes the first time.
Yes they're instantiated with the parameters you give it.
The attribute does not "access" the class. The attribute is attached to the class' / property's attribute list in the reflection data.
[Serializable]
public class MyFancyClass
{ ... }
// Somewhere Else:
public void function()
{
Type t = typeof(MyFancyClass);
var attributes = t.GetCustomAttributes(true);
if (attributes.Count(p => p is SerializableAttribute) > 0)
{
// This class is serializable, let's do something with it!
}
}
Think of attributes are post-its that are attached to the classes or method definitions (embedded in the assembly metadata).
You can then have a processor/runner/inspector module that accepts these types by reflecting, looks for these post-its and handles them differently. This is called declarative programming. You declare some behavior instead of writing code for them in the type.
Serializable attribute on a type declares that it is built to be serialized. The XmlSerializer can then accept an object of this class and do the needful. You mark the methods that need to be serialized/hidden with the right post-its.
another example would the NUnit. The NUnit runner looks at the [TestFixture] attributes all classes defined in the target assembly to identify test classes. It then looks for methods marked with [Test] attribute to identify the tests, which it then runs and displays the results.
You may want to run through this tutorial at MSDN which has most of your questions answered along with an example at the end. Although they could have extracted a method called
Audit(Type anyType); instead of duplicating that code. The example 'prints information' by inspecting attributes.. but you could do anything in the same vein.
If you take an eye out this downloadable open source code LINQ to Active Directory (CodePlex), you might find interesting the mechanism of the Attributes.cs file where Bart De Smet has written all of his attributes classes definitions. I have learned attributes there.
In short, you may specialize the Attribute class and code some specialized properties for your needs.
public class MyOwnAttributeClass : Attribute {
public MyOwnAttributeClass() {
}
public MyOwnAttributeClass(string myName) {
MyName = myName;
}
public string MyName { get; set; }
}
and then, you may use it wherever MyOwnAttributeClass gets useful. It might either be over a class definition or a property definition.
[MyOwnAttributeClass("MyCustomerName")]
public class Customer {
[MyOwnAttributeClass("MyCustomerNameProperty")]
public string CustomerName { get; set; }
}
Then, you can get it through reflection like so:
Attribute[] attributes = typeof(Customer).GetCustomAttribute(typeof(MyOwnAttributeClass));
Consider that the attribute you put between square brackets is always the constructor of your attribute. So, if you want to have a parameterized attribute, you need to code your constructor as such.
This code is provided as is, and may not compile. Its purpose is to give you an idea on how it works.
Indeed, you generally want to have a different attribute class for a class than for a property.
Hope this helps!
Not much time to give you a fuller answer, but you can find the Attributes that have been applied to a value using Reflection. As for creating them, you inherit from the Attribute Class and work from there - and the values that you supply with an attribute are passed to the Attribute class's constructor.
It's been a while, as you might be able to tell...
Martin

Why would one want to use AttributeUsage AllowMultiple when creating attributes?

According to a book I'm reading, the AllowMultiple public property of AttributeUsage specifies:
...whether the target can have multiple instances of the attribute applied to it.
Why would I want/not want to use this?
Attributes are meta-data. Typically, you'll want to decorate a member or type with an Attribute in order to track some information about it.
For example, the DescriptionAttribute is used by the PropertyGrid to label a description of a property:
[Description("This is my property")]
public int MyProperty { get; set; }
Most of the time, having more than one description would not make sense.
However, it is possible that a specific attribute makes sense to use more than once. In that case, you'd want to set the Attribute to allow multiple instances of itself tagged to the same attribute.
(Not that I'd do this, but...) Say you made a custom attribute to track major changes to a class. You might want to list this for every major change:
[Changes(Version=1.1, Change="Added Foo Feature")]
[Changes(Version=2.0, Change="Added Bar Feature")]
public class MyClass
{
// ...
This example might be a little contrived but hopefully it gets the point across.
[Convertable(typeof(Int32)), Convertable(typeof(Double))]
public class Test
{
}
This depends what the attributes are.
For example, you could make an attribute that marks a class as depending on something, and you could allow multiple dependencies.
For a concrete example, look at SuppressMessage, which suppresses a code analysis warning. A member can have multiple warnings that you might want to suppress.
Another example is WebResource; an assembly can contain multiple resources.
No contrived example here, I used it in real production code. I wrote some code to parse a file containing pairs of data like (code=value). I put a custom attribute on a function to indicate it should be called for a given code.
[CanParseCode("G1")]
[CanParseCode("G2")]
private void ParseGXCodes(string code, string value)
{
...
}
This particular format is a somewhat old and domain specific with hundreds of different codes. My goal was to write a framework to make it easier to write file processors that could extract only the codes it needs and ignore the rest. Allowing the same attribute multiple times made it easy to express the intent of the code by simply declaring attributes on the function(s) that process each code.
Real World Application of Attribute AllowMultiple=true usefulness
[ManagesType(typeof(SPEC_SEC_OC), true)]
[ManagesType(typeof(SPEC_SEC_04_OC), true)]
public class LibSpecSelectionView : CustomView
{
public LibSpecSelectionView(SPEC_SEC_OC)
{}
public LibSpecSelectionView(SPEC_SEC_O4_OC)
{}
....
}
public static class ViewManager
{
... static Dictionary of views built via reflection
public void LaunchView(this CollectionBaseClass cbc)
{
... Find class registered to handle cbc type in dictionary and call ctor
}
}
SPEC_SEC_OC myOC = DataClient.Instance.GetSPEC_SEC_OC();
myOC.LaunchView()
I flipped AllowMultiple=true earlier today to allow for the ManagesType attribute to be used more than once. We have several hundred Custom Collection Classes. Most of these custom collections have a view that inherits from CustomView designed to handle creation of a UI view for a specific type of custom collection and presenting it to the user. The ManagesType attribute is used via reflection to build a dictionary of EVERY View in our app that inherits from CustomView to "register" what object type it was designed to handle. The LibSpecSelectionView "broke that pattern" by displaying two different collections at the same time (creates two tabs and shows one custom collection in one tab and the other in the second tab) So the same view is capable of handling two different custom collections.
The dictionary of which views are capable of handling which collection types is then leveraged through an extension method to allow any of our custom collections to launch the registered view (or a default one if there is not a "registered" view) through a one line call to the view manager.

Categories

Resources