text: First I wrote an article about Attributes vs the Single Responsibility Principle. Then I wrote the Converters article in which I presented a generic converter class that conforms with such principle and is really loosely-coupled, allowing users to register their own conversion to any types, making it possible to add conversions to types that do not implement IConvertible, do not declare a [TypeConverter] on their declarations or that are simple from unrelated assemblies.
  IConvertible
  [TypeConverter]
  Then I wrote an article about Actionless frameworks. In it I presented why WPF and my own Converters framework were a kind of actionless framework, but I promised to present a full-featured actionless framework later as even the Converters framework (now renamed to ConversionManagement framework) was not complete in my actionless proposition.
  Now, it is the time to present a full featured actionless framework, and it is the RuntimeExtensionManagement actionless framework.
  To those who didn't read the other article, here is a brief introduction of an actionless framework. An actionless framework is a framework that:
  Before starting with the article itself, I will try to sell the product.
  Using the RuntimeExtensionManagement + the WPF components that are presented in this article you will be immediately able to:
  RecordEditor.Edit()
  The RuntimeExtensionManagement is the namespace and also the name of an actionless framework that allows users to extend any object at run-time.
  As the .Net types themselves also have their objects and you can get all their members from there you can add new information to types, properties, fields and to specific instances.
  Maybe you already do register additional data to your objects at run-time thanks to a Dictionary or a ConditionalWeakTable, but as already presented, the actionless framework must follow some rules, like having global and local configurations, which can become a must on web-services.
  Dictionary
  ConditionalWeakTable
  What kind of extensions can be done?
  Any. But as I know it is hard to simple think with that abstract kind of information, I will start by the ones I am actually using:
  is
  as
  Type
  In the presentation I said that you could add text localization easily. So, are the DisplayNames and Descriptions localizable?
  The answer is both yes and no. The framework only comes initialized with searchers that look for the member name and the [DisplayName]/[Description] attributes. So, without any extra configuration, it is not localizable.
  [DisplayName]/[Description]
  But as an actionless framework you can set/replace the extensions for the items, so you can set better DisplayNames and Descriptions at runtime, and you can add better searchers, capable of looking for those items in the database, resource files or even text files, making all the places that use such extensions completely localizable. It is enough that you always use the RuntimeExtensionManager to get those texts and the components that will be presented do exactly that.
  Another question that some users may ask is how I am keeping those RuntimeExtensions in memory.
  Well, when adding data to objects at run-time we are inevitably using some kind of dictionary. But that can be global, so it needs a static variable.
  The problem then is: If we put a value for an item inside a static dictionary, both (the item and the value) will only be collected when closing the application.
  That's why the implementation uses a ConditionalWeakTable. While the main object is alive, the additional info will be kept alive. If the original item is collected, the extra info is also able to be collected (if there are no other references).
  But when adding extra info to value types we don't have such chance, as each time we receive a value-type as object we are receiving a new boxed value. So, to solve those cases, if the main object is a value type, a normal Dictionary is used. In this case, RuntimeExtensions made to value types are never collected (if added globally).
  That's what happens to DisplayNames set to enums, for example. But, in that case, I really consider it is not a problem as we have a limited number of enum-values. But take care not to add extra info to all possible integer values.
  MemberInfos: I always believed that the Types and MemberInfos were always kept in memory once loaded. I was wrong and in another application I discovered such behavior, that became a bug to my library. So, extensions to enums and to MemberInfos are stored in a normal Dictionary. This way, there is no risk of attributes put on FieldInfos and PropertyInfos to be collected.
  MemberInfo
  FieldInfo
  PropertyInfo
  If you are only interested in creating your own runtime extensions, you can jump to: Using the framework - Creating your own extensions.
  The entire idea of this framework is to create really loosely coupled applications as it allows to search DisplayNames, Descriptions and to register factories for data-types freely.
  But allowing to register all kinds of editors is one thing. Creating and registering those editors is another thing. Using them is still another.
  And to use it I already created many components that can get the right controls, show the right display names and descriptions and, as I see it, this is the easy part of the framework and the one that will be used most of the time. So I will start by presenting the easy part but, before starting, I want so say something about RAD.
  I think that I should talk about RAD a little. The reason is simple. I usually see RAD as a bad thing. Before using Delphi (and later Windows Forms, which is very similar in concept) I created my user-interfaces by code.
  It could be harder, but at the same time that made me think in ways to automate the repetitive work and usually that gave me better aligned, resizable and localizable controls. It was simple, the code to create new controls could store some info (like the position of the next control, the place where search texts from etc) and then use it when creating the controls.
  But the IDE from Delphi was surely easier to use to create a new window really fast and many new programmers never created controls by code. They simple didn't know what to do if they needed to.
  So, a thing that was helping from one side (creating a new form really easy and even placing the controls at exact positions), was making things harder at another side (as directly placed controls were not resizable, direct written labels were not localizable and so on).
  Then there were the Wizards and Code Generators. In special, if you selected some table fields and drag-dropped them to the window, the "right" DBAware controls were automatically created and put one below the other on the window. But, after, they were there, so you were free to move them and create a better layout but at the same time, if the data-type changed, they stayed there, and I often saw people deleting controls to drag-and-drop the field again only to get the new right control.
  And I can go one step further and say that in some cases, the default DBEdit or DBCheckBox was not the right control but looked like the right one. What if the right control was the MyDBEdit?
  DBEdit
  DBCheckBox
  MyDBEdit
  To try to avoid those problems (or simple because it seems better to make everything automatic), I also saw some enterprises working with run-time only generated UIs. Any data-type change and any new columns were automatically put into the forms as all the controls were generated at run-time by some kind of table analysis.
  With some simple rules, the application was fully localizable, there were no tables without an editor form... but it was a chaotic situation when manually edited forms were needed, as everything was simple automatic, with almost no space for manual editing. Some events were created to try to solve the situation, but that meant that the form was created with the wrong controls and the event was responsible for finding them by name (or even index), deleting them, creating the new controls and usually it was also needed to change the position of the other controls.
  So, even if the RAD with wizards were bad, the automatic UI generation was even worse. It could help in the creation of 50 simple forms, but that one complex form was so hard and time-consuming to create that it would be better to create all the forms by hand.
  In my opinion a good RAD is one that allows the developer to immediately create all forms of the application with little or no effort at all, exactly like those run-time generated UIs.
  It should also automatically reflect changes in data-types or table structures. Again, as those automatically generated UIs.
  But it should allow the developer to easily create specific forms, avoiding some of (or even all) those automations. And that's what I tried to do.
  My idea is that, by default, all records use a default editor that simple puts one control below the other, already using the DisplayName and Description searchers that can be localizable.
  DisplayName
  Description
  If that's not good, you can replace a specific record editor, but you are not forced to do the entire "form" by hand. You can put some controls at their right places by hand, but still ask them to use the right runtime data-type editors. Then, if you want, you put another control that will edit all the remaining properties using that automatic rule, so future properites will be immediately editable.
  In my opinion, this makes the developer free to use the automatic features, never having a table without an editor (for example) and also free to create specific record editors if the default ones are not good looking or simple hard to use.
  An extra feature is that when a new specific record editor is created, all the places that were calling the generic editor should start calling the new editor without changes on how the call is done, avoiding boring and error prone search and replaces like new GenericRecordEditor<Person>(record) by new PersonEditor(record).
  new GenericRecordEditor<Person>(record)
  new PersonEditor(record)
  Well, that's what I tried to do, so let's see how it works.
  Now I will show how you can use the framework in a WPF application. It is RAD but I really believe it is nearer the right way of doing things.
  By a simple call to RecordEditor.Edit(someRecord) you can edit any object. If there is a specific editor registered, it will be used:
  RecordEditor.Edit(someRecord)
  If there is not, a more generic one will be used:
  Using the RecordEditor.Edit() is the preferred way to edit a record. The caller simple does not need to care what is the type of the record. It is not forced to know that a Person is edited by the PersonEditor, and that an Enterprise uses the generic editor. Simple do the call and let the right editor be used, be it an automatically generated one or a hand-crafted one.
  PersonEditor
  By default when you edit a record a new window is created. That default action can be replaced, but that's not the case now. For some reason you may want to put a specific record editor inside your window without replacing the default behavior.
  That's the purpose of the RecordEditorControl.
  As a control, you can put it anywhere. It is enough to say the data-type to be edited and the right editor control is used. Again, be it automatic or hand-crafted.
  To use it, you can use a code like this:
  <PfzWpf:RecordEditorControl
  The Type property is type of the record to be edited and the IsEditorToolbarVisible, which is true by default, tells if the record editor should show the editor toolbar (usually the OK/Cancel button) or not.
  IsEditorToolbarVisible
  Well, you know that you can edit a record anywhere by a simple call to RecordEditor.Edit() but that default editor is not good. So you want to create your own record editor.
  Later I will explain how to register that editor, but now let's see the controls you will probaly use to do the job.
  This control is bound to an entire object, and this is the one that simple puts one property below the other, using the right data-type editor.
  In it you can tell which properties to avoid, making it prepared to edit future created properties without requiring to change the control definition to include such properties or you can tell exactly what properties you want it to edit.
  By creating some of those controls in your record editor you can already create a better layout but, if you want to create an ObjectBoundControl to edit a single property, then it is better to use the PropertyBoundControl.
  ObjectBoundControl
  PropertyBoundControl
  You can use it like this:
  <PfzWpf:ObjectBoundControl
  {PfzWpf:Properties}
  TypeConverter
  Properties
  This control is bound to a single property and the ObjectBoundControl simple creates many instances of this control, binding each one to a different property.
  When bound to a property, it is capable of finding the DisplayName, the Description and the right value-editor to present those informations and also edit the property value. It is also capable of detecting if the property or the record being edited is read-only.
  If you don't want to use the default DisplayName or Description you can always set such properties on the control directly, replacing those defaults.
  With this control you are free to create your layout as you want but, still, use the right data-type editor. If the property type is changed in the future you may need to correct some code, but the UI will be ready to use the new property type.
  Here is a sample declaration:
  <PfzWpf:PropertyBoundControl
  Property
  {PfzWpf:Property}
  The PropertyBoundControl is great to edit a property value but for some reason you simple want to edit a value without creating a property. You know the data-type, but you don't want to put the specific editor directly as it may change in the future.
  So, put a ValueEditorControl and set its Type ot its default Value directly. It will find the right editor to edit such value. It is also capable of presenting a DisplayName and a Description and, as you may have already figured it out, this control is used by the PropertyBoundControl.
  ValueEditorControl
  Value
  The PropertyBoundControl and consequently the ObjectBoundControl are already prepared to search the right DisplayName and Description for properties they are bound to, which can be localizable.
  Following that idea you may want to create other texts that are localizable (or could become localizable in the future). By using the {DisplayNameWatcher} and {DescriptionWatcher} XAML extensions you can achieve that.
  {DisplayNameWatcher}
  {DescriptionWatcher}
  You will need to inform a Type and a field-name (not a property) to use as the source to get the right text. As enums values become fields, you can declare your texts like this:
  public enum MyTexts
  {
  [DisplayName("Quit without saving")]
  [Description("Quits the application losing any changes you've made.")]
  QuitWithoutSaving
  }
  Then in your XAML you will use something like:
  {PfzWpf:DisplayNameWatcher {x:Type App:MyTexts}, QuitWithoutSaving}
  or
  {PfzWpf:DescriptionWatcher {x:Type App:MyTexts}, QuitWithoutSaving}
  And your code will be prepared to be localized if a localizable Displayname or Description is registered.
  Displayname
  You already started to use the RecordEditor.Edit() in your application and it is saving you a lot of work (at least I hope it is). Instead of creating 100+ editors to edit simple objects, they are all being edited by the default editor.
  But the Person type has a Photo (to which the default implementation is saying it can't find an editor for byte[]) and many document numbers that are simple presented by unformatted textboxes. You want to show the photo, which a Capture button at the bottom and to format and validate the document numbers.
  byte[]
  What should you do now?
  Two solutions
  Before continuing, it is important to understand that there are two main approaches to solve the problem.
  My recommended approach is to create new types for everything that has a specific single-field validation or presentation. So, a Photo should not be of type byte[], it should be of type Photo or, at least, of type Image. By the same principle, each document type will also have a specific type instead of using string/int. So, a driver-license is not of type string, but of type DriverLicense.
  Photo
  Image
  string/int
  string
  DriverLicense
  This helps the automatic record editors find the right value editor controls by looking at the data-type. In this case, your main focus should be to create value editors (IValueEditorControls). You may still want to create entire record editors (IRecordEditorControls), not because the default record editor was not formatting or validating something, but because you want a better layout or specific functionalities in the editor.
  IValueEditorControl
  IRecordEditorControl
  But having a new type to do the validations or to havethe initial knowledge of which value editor to use may not please you or it may not work with your ORM. Maybe you use an ORM that is simple incapable of dealing with a Photo type, it should use a byte[] type and you don't want to create wrappers objects, as that will increase the amount of work to be done and, in that case, you will be only moving the problem from one place (the editor, which you need to do only once) to another (requiring to create a wrapper before editing, everytime). In that case, you will really need to implement a new record editor control.
  Maybe you are already in doubt, maybe you will get in doubt at the moment you are about to implement an editor or maybe you simple got it from the first moment.
  But sometimes people get confused if they should use/implement a value editor or a record editor. For example, the actual Person editor is not good, and you want to create a new one. Which one should you implement?
  Person
  The answer can be related to inner data. Do you already have a Person object and you want to edit its properties? Or do you want to create a lookup, maybe?
  An IRecordEditorControl is responsible for editing the inner content of an already existing record. Maybe it does a search too, but that's not its main purpose. On the other hand, an IValueEditorControl does not care about the inner content. It always gives you an entire new object, even if it is an object already in memory.
  So, for a Person you may want to create a value editor that is a Lookup (used to edit properties of type Person) and a record editor that will edit an actual Person instance contents.
  To illustrate the situation, Colors are edited using a text-box by default, simple presenting their hexadecimal values:
  Color
  But you are free to create and register a better editor:
  A value editor control has the purpose of editing data of some type and it return new values instead of changing an already existing object. It can be used to edit strings, booleans, Colors or even a DriverLicense doing the required formatting and validations.
  bool
  To be a valid value editor control to this framework, it should implement the IValueEditorControl interface.
  Such interface requires the control to support IsReadOnly (many of my implementations simple use the reversed IsEnabled value), Clear() and the Value property (inherited from IValueContainer).
  IsReadOnly
  IsEnabled
  Clear()
  IValueContainer
  The interface does not have an way to tell this, but for WPF applications the editor must be a FrameworkElement sub-class. I always create an UserControl, make it implement the IValueEditorControl interface and fill its Content with the appropriate editor (usually they already exist, like a TextBox, a CheckBox and so on).
  FrameworkElement
  UserControl
  TextBox
  CheckBox
  Ok... you did it and now you have the impulse to put the control directly on the window where you need it.
  Well, don't do it! That will be a direct reference and you should avoid direct references. You should now register the control on the ValueEditorControlFactoryManager.
  ValueEditorControlFactoryManager
  I know, it is a long name, but I tried to make it clear: it is the extension manager of factories that create value editor controls. So you should create a factory too. Creating the factory is easy, simple inherit a class from the ValueEditorControlFactory and implement the OnCreate method to return a new instance of your control.
  ValueEditorControlFactory
  OnCreate
  Then you should register that factory into the ValueEditorControlFactoryManager for the right data-type. If you simple want to register it to the entire application, do:
  ValueEditorControlFactoryManager.GlobalRegister(typeof(YourDataType), new YourValueEditorFactory());
  Note 1: Do not inherit from TextBox (or other similar control) directly, as the control templates registered at application level will not be valid to the sub-classes. Always create an UserControl and put the existing control (the TextBox, for example) as the content.
  Note 2: In my implementations I usually create a singleton instance of the factory and I really consider that to be the right approach to avoid creating many instances of a type that has no data or if you want to unregister the factory later, but to make things simpler here I used the new YourValueEditorFactory().
  new YourValueEditorFactory()
  A record editor control is a control capable of editing an entire record, and it usually changes the content of that record instead of creating new instances.
  As happens with the value editor controls, I always create a new UserControl, but in this case I make it implement the IRecordEditorControl interface.
  Such interface has the following traits:
  PropertyBoundControl.ApplyChanges(DataContext)
  Visibility
  Visible
  true
  false
  Collapsed
  Finished
  In the XAML part of the control you will probably use a lot of PropertyBoundControls and maybe some ObjectBoundControls. Then, after finishing the control, the process is again very similar to the IValueEditorControl.
  You will need to create a RecordEditorControlFactory, which will create your control, and you should register it with a line similar to this:
  RecordEditorControlFactory
  ValueEditorControlFactoryManager.GlobalRegister(typeof(YourRecordType), new YourRecordEditorFactory());
  Lately I consider impossible to hear WPF without thinking in MVVM, so it is natural to want to know if this framework is MVVM friendly. And the first answer is no, but don't worry.
  You can still use MVVM when you are creating your IRecordEditorControls but when I say that the first answer is no, I am refering to the main purpose of MVVM and the main purpose of these components.
  MVVM is all about having independent View and Model and the components I am presenting are about creating the View automaticaly from the Model and, if the automatic is not good, then manually creating a better view for that model. So, at the first moment there is no MVVM at all, and it should not be. The purpose is to reduce the amount of code written to do simple things.
  Also, another thing that I question myself is the need for a ViewModel in many situations. In a correct MVVM implementation you should never put a binding converter on the View, as the view should avoid anything that can be seen as code related, and you should put the properties with the View expected type on the ViewModel, doing a conversion from a Model property if necessary. For example, a property IsValid (of type bool) may be presented on the ViewModel as OkVisibility (of type Visibility).
  IsValid
  OkVisibility
  In such case I would love to replace the default Binding converter. But, as I can't do that, I can simple tell that every binding should be a ConvertBinding. As the designers will not need to know what Converter to use, I can say they will not be doing programming related stuff. If a conversion does not work, then it is the responsibility of a programmer to register the right conversion on the framework. Of course it will be still better if I could replace WPF default converter, but at least I am avoiding that a designer needs to know what conversion to put in the view, and I am also avoiding rework if the property type changes as the ConvertBinding will search a conversion for the new type.
  Binding
  ConvertBinding
  Converter
  So, what is the purpose of the ViewModel in that case? If you still need it because you want to present an enum as three different boolean properties, then OK, create it. Maybe if you simple need to invert a boolean value (like HasErrors instead of IsValid), then you will still need to create it. If your Model does not implement INotifyPropertyChanged and you want to implement it in a ViewModel instead of the Model itself, then do it. If not, you can simple bind things directly to the model and let those components deal with the right types and conversions at run-time. If later you need to create a ViewModel, I am sure you will be implementing your own record editor too, so make the record editor instantiate the right ViewModel for that Record (which is the effective Model) and everything will work as expected.
  INotifyPropertyChanged
  My final word is: You will only need to care about MVVM if you need to create different Views (IRecordEditorControls) and, even then, you may have the option to start without ViewModel, only adding it only if it becomes a need.
  Creating controls and registering them may not be real hard, but it is not as easy as simple putting an existing control on the window. But by simple using the framework you will see that any record is edited by a default editor. What if you want to replace that default editor?
  Or, what if you want to create a new editor that is valid for a type and any of its sub-types? For example the default editor continues to exist and edits any objects that are not DatabaseRecords, and you want a default editor for DatabaseRecords which is capable of saving the records before returning them.
  DatabaseRecord
  Also, I talked about the localization a lot. So, how is it possible to add localization in this framework?
  To all those questions the answer is: Searchers.
  The searchers are invoked when a specific extension (be it a DisplayName, a Description, a record editor factory, etc) is not found for a given item.
  The searcher is then responsible for analyzing that item and, if possible, giving a result.
  So, considering you have a DatabaseRecordEditor that already uses an ObjectBoundControl to edit all the properties of a record and also has database specific tasks, considering that you already have the factory for it, now you want to register it as the default editor for all the DatabaseRecord sub-types.
  DatabaseRecordEditor
  A naive implementation will simple register the same factory for each record-type. But then you will need to do a new registration each time a new record type is created. A better implementation will create and register a searcher.
  The searcher should:
  type.IsSubClassOf(typeof(DatabaseRecord))
  SetResult
  I consider this both the hardest and the less problematic part. Usually, for large systems, such things will only happen once for extension type.
  So, a localizable searcher for DisplayNames and Descriptions will be created. A searcher to edit database records in general will be created. And it's done.
  The default searchers have low priorities (the ones that always generate values have a int.MinValue priority) so any other registered searcher will take precedence over them.
  We can resume the default configuration as the following:
  enum
  [DisplayName]
  [Description]
  There is a little catch on how the WPF components work, and I simple can't get rid of it.
  The .Net framework does not initialize a library before it is used for the first time and, even if the RecordEditor class seems to be part of my WPF components, it is not, it is part of the base library.
  RecordEditor
  The Pfz.WpfControls library, when initialized, registers the default WPF controls to edit records and values. So, if you already used a DisplayNameWatcher, a DescriptionWatcher or some control of the Pfz.WpfControls library, everything will work. If not, you should initialize the library by yourself.
  DisplayNameWatcher
  DescriptionWatcher
  It is very simple, put the following line on the App class and everything will be fine:
  Pfz.WpfControls.DefaultConfiguration.Initialize();
  If you want to try, you can replace the App.cs code on the sample project by the following code:
  using System;
  using System.Windows;
  using Pfz.FactoryManagement;
  namespace RuntimeExtensionsSample
  {
  public partial class App : Application
  {
  static App()
  {
  Pfz.WpfControls.DefaultConfiguration.Initialize();
  RecordEditor.Edit
  (
  new
  {
  Name="Test",
  Address="Unknown",
  Apartment=123,
  Smokes=true,
  PreferredDateTimeKind=DateTimeKind.Local
  }
  );
  }
  }
  }
  And you should see a maximized window that looks like this:
  And yes, it is editing an anonymous type, which is read-only and, if you noticed, the title is the name of such anonymous type.
  Maybe you are already worried about performance. Maybe you are thinking that if you create a big system using all those run-time extensions it will become extremely slow.
  Well, I don't have something to show, but I can talk about some things:
  The sample application registers and unregisters many of the default configurations only to show that the same declared window can greatly change by some configuration changes.
  It also adds application specific configurations showing, for example, that it is possible to present editors as normal/modal windows or to incorporate them into the main window and how it is possible to apply localization in your application.
  But, as a sample, it is very incomplete. I didn't do the translation of every text in the application. Also, I complained about RAD and I did the same thing: some texts are written directly into the main window, without using the {DisplayNameWatcher} so they are simple not localizable.
  Finally, in this application I am always registering every configuration globally. For web servers/services, at least the translation searchers must be registered locally, so different users can have different translations.
  Yet I hope it is useful to show how the framework can be used.
  I was already criticized sometimes because I put my personal library as part of the download. And I am doing it again.
  In this case, you will also benetif from the BinarySerializationManagement namespace, an actionless framework that you can use to create binary serialization of any object, as long as it is possible to serialize it (serializing a ReaderWriterLock is not a good idea) and the ConversionManagement namespace, another actionless framework that you can use to convert objects from one type to another, which is already used by the WPF controls.
  Yet, there is more. In some cases the extra classes and namespaces may be easy to cut-off. For example, the Remoting may not be of interest to you, and it is really easy to remove as the actionless frameworks don't depend on it. But the Caching or the Threading namespaces are not so easy, as the implementation of the actionless frameworks themselves use them. But I really hope that's not a problem. I never used most of the classes in the System.dll but I still use the full version of the library.
  The WPF sample is great (at least I think it is) but you don't want to use WPF, you don't want my factories but you are still interested in adding run-time extensions to your objects.
  So, how do you do that?
  Your extension should be a new class. Even if I did not force a specific base type, creating an extension of type string is bad. Even if the important info is an string, you should still create a type to contain that info.
  That's why I have the DisplayName and Description classes. They both contain a string, but with their type I know exactly what kind of extension I am getting.
  If you simple want to add a boolean flag over your items, like my IsRemotable info, then don't put any attribute in your type, and make it have a singleton instance.
  If the extension is added, then the value is true. If the value is not added, then the value is false. Simple, isn't?
  If on the other hand you want to put many properties, then add all those properties to your extension type.
  You can already start putting your extension over other objects by using the RuntimeExtensionManager generic type, using your extension type as the generic parameter.
  You can add extensions to already existing instances, be it simple objects, types or anything else.
  But you will probably consider the RuntimeExtensionManager type too generic. Maybe you created your extension having in mind it will be put over types, not over entire instances. Also, writing RuntimeExtensionManager<YourExtensionType> is a lot of work.
  So, here is the moment you will probably want to create your own types. The ones I propose are:
  This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)