| | Flexible Opf3 is fully extensible. You may implement a few interfaces (within your persistent objects) or subscribe to events to extend the framework. User Defined Types (UDTs) are also a cool way to extend the possibilities. Opf3 supports also inheritance of persistent objects. The framework supports also logging of the operations done in the database and framework. Interfaces The framework offers interfaces to extend your persistent objects or the framework itself. Some of them are: IStorage | Implement your own storage: you only need to implement this interface to do that. | IQuery | You have a cool idea for a new query language. Implement this interface and you may use your query language everywhere in Opf3. | IConcurrencyManagery | Opf3 ships with a standard concurrency manager, which generates MD5 hashes to do checks in multi user environments. By implementing this interface you can create your own concurrency manager. | IObjectNotification | This interface is implemented by your persistent objects. Opf3 sends notifications to persistents implementing this interface. These notifications are send before and after the object is loaded, inserted, updated, deleted, populated. | IDynamicExtensible | Your datatable is dynamic. You don't know all fields of the table. Implement all you know as properties and the other are stored in a name key collection, when implementing this interface. | IPopulateHelper | The framework is using reflection (in combination with some caching algorithm) to load the properties' values. By implementing this interface you can hard-code that step into your persistent object. Reflection is no longer required. | ISelfContainingObject | By implementing this interface the persistent object itself takes care of its state. By default the framework does the state management for each persistent object. When implementing this interface the persistent object itself takes care of the state management. This interface is usually implemented when you remote or serialize an object (when an object leaves the current AppDomain. | IUserDefinedType | This interface is implemented on a class that's data is stored to a single field of a table. You have, for example, some complex data you want to store as XML in a field. No problem: Implement this interface on that object. Opf3 will ask you the XML representation on each save and return that XML on every load. | Events The framework contains a few places where you can subscribe to events. One of those places is the ObjectContext. Here you have access to events which are fired on each load, update, delete of a persistent object. Another powerful event mechanism is implementing the IObjectNotification interface in your persistent object. You get then an event for every action that is taken on the persistent object. Inheritance model Opf3 features a rich inheritance model. You may define base classes which contain already some bound properties (or member fields), inherit from that class and override those properties with own code or set another attribute to bind the property to another field. If you override a property and don't set a new FieldAttribute the attribute of the base property is used. The framework allows also create different object types depending on the value in a field in a data table. You load, for example, a few entries of a table and decide depending on the value in the first column of the table which persistent type to create. That's possible in Opf3! (Look for PersistentTypeSelector in the documentation) Logging Opf3 supports also logging of all changes and all operations done on the database. Errors or warnings of the framework framework are also logged. The log may be written to a database, file, or something else. The system is very flexible and extensible. |