Application development using an object model

The aim of generating an object model is to make it easier to use a DataStore from a .Net language such as C#.

The code generation is performed by custom directives for T4 templates. The custom directives are supplied by the Visual Studio Extension "DataStore T4 Directives". The generator uses annotations to control generation.

The object model code generator allows a DataStore to be represented as an object model. It creates classes based on the DataStore's ItemTypes, with the AttributeTypes and AssociationTypes of the ItemType are used to create properties of the class. The generated classes use, or are derived from, the classes contained in Semata.DataStore.ObjectModel.

In addition, the code generator can create a set of classes that are views on the object model. These are designed to facilitate their use from WPF, and use, or are derived from, the classes contained in Semata.DataStore.ObjectModel.Views.

The generated code uses classes in contained in Semata.DataStore. However, these classes should not be used from custom code, as it would conflict with the object and transaction management (the only exception to this is when implementing the AfterCreate and BeforeOpen partial methods of the DataStore class).

Custom Code

To complete the application custom code will be required. The generated classes are all partial so can be extended. You can add custom code to the template file, but this is not recommended. It is alot better to have the custom code in a separate file.

The generated classes define partial methods that are used as callbacks. ItemObject has partial methods called at specific times, when they are written, deleted etc. ItemObjects are sealed with methods like Write() and Delete() not virtual.

Views are designed to be inherited, with the methods Write and Delete virtual. Views just have one callback, OnInitialize, which is called at the end of the view constructor. Most customisation occurs with the Views. (see Order Processing)

There can multiple ItemObjectViews for one Item whereas there can ony be one ItemObject.

Transaction management

DataStore does not provide nested transactions, but the DataStoreClass does. This is so that code that can be called on its own, or as part of a larger transaction, will perform as expected. The DataStore transaction starts with the creation of the outermost level, and is committed when the outermost level is committed. So the nesting just really performs housekeeping to start and commit the transactions at the right time.

The properties of the View classes have the type object rather than the value type of the particular wrapped attribute. The reason for this is that during editing the value of the property might pass through states when it is invalid for that value, and will be just returned as a string.


ItemObjects raise PropertyChanged when one of its properties is changed, and PropertyWritten when that change is committed to the DataStore.

ItemObjectViews subscribe to PropertyChanged (depending on the state of UsesPropertyChanged ) and PropertyWritten of the ItemObject. they are views of. When these events are detected it raises PropertySourceChanged, which is a signal to its properties that their source has changed. It is then the resposibility of the property to raise PropertyChanged, once it has carried out any necessary processing in response to the event. when that change is committed to the DataStore. When PropertyChanged is raised StateChanged is also raised


DataStoreObject and ItemObject both implement IPropertyChanged. It provides notifications when an Attribute is changed, an Item is created or deleted, and when an Association is added or removed. It only provides notification if the action was explicitly performed by the object model. E.g Associations removed because an Item is deleted are not reported.

It also provides error notifications. Any exception thrown by code in the object model, is caught, PropertyChanged fired and then the exception re-thown. This is done as on some platforms exception do not propagate through the dat binding layers.

It provides the notification by sub-classing PropertyChangedEventArgs.

The object model code could be running on a thread different to that of the UI when the event is fired. So when a DataStoreObject is created a delegate can be provided that will fire the event on the correct thread. See Expenses sample.

This website stores cookies on your computer that are used to manage the order in which you see the pages. To find out more about the cookies we use, see our Privacy Policy.