Architecture Storages Opf3 is a layered framework. The bottom of the Image 1 shows the physical storage. It is any kind of database or also a file that allows to save structured or semi-structured data. To make a physical storage accessible from the framework you have to create a class that implements the IStorage interface. If the storage should also support transactions the ITransactionStorage interface has to be also implemented. The framework ships with pre-build storages for the most common databases such as: MS SQL Server 2005, MS SQL Server, MS Access, Oracle and other. The ObjectContext Above the IStorage layer sits the ObjectContext. The ObjectContext is the class allowing to load, save and delete single objects or list of objects from/to the storage. Each instance of the ObjectContext class can also be connected with an instance of a class that implements the IConcurrencyManager interface. A class implementing this interface does optimistic locking. On each update it checkes whether the object has been altered in the storage while being in memory. If somebody else changed it you get an ConcurrencyException.  Image1: Layer of Opf3 Queries To specify the persistent objects loaded from the storage a class implementing the IQuery interface is used. The framework comes with two different classes: the ObjectQuery and the SqlQuery. ObjectQuery is a storage independent query that is compiled to a storage dependent query (CompiledQuery) before fetching the persistent objects from the storage (this is done by the framework). SqlQuery is a type of query that allows you to specify SQL. You can create an instance of the SqlQuery class and use it on any of the storages that ship with the framework. Get objects from the storage On top of the ObjectContext you find different classes. Those classes are returned by the ObjectContext or used to get persistents from the storage. The ObjectSearcher class, for example, is a specialized class that allows to load objects from the database. By deriving from ObjectSearcher you may implement your own specialized "searcher" classes. It's highly recommended to inherit from ObjectSearcher to encapsulate complex queries (for an example see the ObjectSearcher documentation). When loaidng persistents the ObjectContext class either returns a single persistent object or a list of objects. The framework ships with a class named ObjectSet which holds a list of persistent objects. You may also load the persistent objects to any class implementing the IList<T> interface. Storage Cursors The ObjectReader class implements a forward-only storage cursor. It has methods to advance to the next object in the storage or to move ahead to an object at a given index. You may use this cursor in your application to do exports or to minimize the memory and bandwith overhead. Persistent Objects Persistents may no longer inherit from any special class. You may implement your own base class from that you inherit your persistent classes, but it's not required. The framework ships with a few interfaces that may be implemented by your persistent classes to extend its functionality. |