This website is intended as archive for old content and forums.
Please visit http://opf3.codeplex.com for the project's new website.

Opf3 Wizard Documentation

Getting started with the Opf3 Wizard

The Opf3 Wizard is an application that allows you to create different objects from a database schema. The tool is not limited to just create persistent objects for the Opf3 Framework. It rather allows you to create every possible object from a given database schema.

To achive that goal the wizard does not implement any scripting language, but provides you an interface (IObjectProvider) that you may implement to create your own plug-in. The plug-in has access to all data that is fetched by the wizard and some other basic data that may be required to create the objects.

For a very simple implementation of a plug-in look at the Chili.Opf3.Wizard.SimplePlugin project. The sample comes with the Opf3 Wizard sources (Attention: Not included in the demo version).

You could imagine a scenario where the wizard creates the persistent objects and also a simple UI that does already the databinding for you. Everything is possible.

How to work with projects?

The Opf3 Wizard allows to save the retrieved schema and customized settings as a project. You can use that project again when fetching the schema another time. The tool includes an engine that extracts the differences and adds or removes tables, views, fields, indexes or relations.


Image1: Project management with the Opf3 Wizard.

Image 1 shows the project management features of the Opf3 Wizard. To open a project click the "Open project..." button [1]. A open file dialog should appear where you select your project. Opf3 Wizard projects have the extension .wpxml (stands for "wizard project xml"). After having loaded the project the label [3] shows you the file name of the project.

To create a new project, just click the "New project" button [2]. When creating a new project nothing special happenes in the UI. If you had loaded a project the label [3] is set back. If you hadn't loaded anything the Opf3 Wizard does an internal reset to an empty project.

The project is only saved when the wizard is closed.

How to select the plug-ins that are executed?

The Opf3 Wizard comes with a plug-in based architecture. The architecture allows you to extend the tool by adding new plug-ins. This allows to use the wizard to create other objects, then the persistent objects, from a database schema. The current implementation of the wizard creates already persistent objects, test objects, index based searcher classes and interfaces. But these are only a few samples of what you can do when extending the program.


Image2: Selecting plug-ins in the Opf3 Wizard.

Image 2 show the first page of the wizard. The list marked with [1] holds all plug-ins that have been found while the wizard has been started. All plug-ins in the same directory as the wizard executable are listed here.

To have a plug-in executed you need to check it here. To proceed at least one of the plug-ins must be selected.

How to add a storage?

To add a storage you need to click the "Add..." button (see Image 3 [1]).


Image3: Add a storage.

After having clicked the button the dialog to add the new storage (Image 4) pops up. Please enter in the "Alias for the storage" text box [1] an alias for the storage. This alias is shown in the storages combo box of the main Opf3 Wizard window. Next you need to click the "..." button [2]. This button openes the Microsoft Data Link Properties dialog.

Select in that dialog the OLEDB provider for you database system and enter all required data. Click OK after having finished. Now you should see in [3] the connection string for your database.


Image4: Manage storage dialog.

Click OK to have the storage added to the list of storages managed by the Opf3 Wizard. The list of storages is project independent. Each project saves only the selected storage. You may add more storage because you can reuse them in each project.

Finally check or uncheck the check box in Image 3 [2]. Checking this check box tries to rename the returned data to singular. This works very well for English, but does not perform well with other languages.

How to avoid an error during the load of the schema?

If you are getting an error message during the load of the schema it is most porbably a problem with the OLEDB provider for your database. The Opf3 Wizard uses OLEDB to fetch the storage's schema. OLEDB is used because it offers a standardized way to retrieve a storage's schema. Please make sure to create the connection string by using the OLEDB provider for your database.

Another issue could also being the user having not the required rights. Please take a user that has the rights to read the schema of the database when creating the connection string for the storage.

If you are getting the error for any other purpose, please contact us.

How to manage the storage's persistent objects?

Image 5 shows the list [1] holding the persistent objects found in the database. The list contains up to three different categories. In the image the Opf3 Wizard has only found tables (we have therefore only one category visible). The tools does also search for views, which is the second category. If you add a custom persistent object that is shown in the thirth category, with name "Default".


Image5: List of persistent objects found in the database.

The three buttons "Add...", "Edit...", "Remove" [2] in the bottom left allow to add, edit or remove a persistent object to/from the list. A removed item is no longer updated when the project is loaded again and a load of the schema is done (the diff engine knows that the item has been removed).

In the bottom right corner [3] you find two buttons: "Check all" and "Uncheck all". Those two buttons allow to check or uncheck all persistents. An unchecked persistent is not equal to a deleted one. It is still updated when doing a second load, but the wizard does not create an output for it. Unchecking is the same as disabling the output for it.

How to add/edit a persistent object?

To add a persistent object click the "Add..." button, to edit a persistent object click the "Edit..." button (see Image 5 [2]) in the bottom left corner of the wizard's main window. The dialog in Image 6 should appear.

General page


Image6: Edit general settings of the persistent.

Image 6 shows the "General" page of the persistent object. The two text boxes [1] specify the name of the database entity (table or view) and the class name for the persistent object.

The "Pool size" nummeric up down control [2] allows to specify the pool of empty persistent objects created for the class (see PersistentAttribute). Attention: This has nothing to do with caching, it is just a pool of empty objects, to speed up heavy loads.

The last items are the "Rights for the persistent object" [3]. You may specify here the different rights of the persistent object. If the persistent is created from a view all rigts are unchecked then the right to load the persistent object. Rights specify if the persistent object can be loaded, saved, inserted or deleted. By checking all of them the persistent has all possible rights.

Properties page


Image7: Edit the properties of the persistent.

Image 7 shows the "Properties" page of the persistent object. The list [1] shows the properties that have been found for the persistent object. Each properties corresponds to one field in the database's entity.

The three buttons "Add...", "Edit...", "Remove" [2] in the bottom left allow to add, edit or remove a property of the persistent object to/from the list. A removed item is no longer updated when the project is loaded again and a load of the schema is done (the diff engine knows that the item has been removed).

In the bottom right corner [3] you find two buttons: "Check all" and "Uncheck all". Those two buttons allow to check or uncheck all properties. An unchecked property is not the equal to a deleted one. It is still updated when doing a second load, but the wizard does not create an output for it. To find out more about editing a property click here.

Indexes page


Image8: Edit the indexes of the persistent.

Image 8 shows the "Indexes" page of the persistent object. The list [1] shows the indexes that have been found for the persistent object. The image shows that there have been found 3 indexes: one is the primary key, one is the index for the primary key and one is a custom index on "EMAIL".

The three buttons "Add...", "Edit...", "Remove" [2] in the bottom left allow to add, edit or remove an index of the persistent object to/from the list. A removed item is no longer updated when the project is loaded again and a load of the schema is done (the diff engine knows that the item has been removed).

In the bottom right corner [3] you find two buttons: "Check all" and "Uncheck all". Those two buttons allow to check or uncheck all indexes.

Relations pages


Image9: Edit the relations of the persistent.

Image 9 shows the "Children" and "Parents" pages [4] of the persistent object. The list [1] shows the relations that have been found for the persistent object. On the "Children" page all relations are shown where the object has child persistents (the child persistents hold a foreign key to the parent). In the "Parents" page all relations are shown where the object holds a foreign key to another persistent.

The three buttons "Add...", "Edit...", "Remove" [2] in the bottom left allow to add, edit or remove a relation of the persistent object to/from the list. A removed item is no longer updated when the project is loaded again and a load of the schema is done (the diff engine knows that the item has been removed).

In the bottom right corner [3] you find two buttons: "Check all" and "Uncheck all". Those two buttons allow to check or uncheck all relations. An unchecked relations is not the equal to a deleted one. It is still updated when doing a second load, but the wizard does not create an output for it. To find out more about editing a relation click here.

How to add/edit a persistent object's property?

To open the dialog to add a property to a persistent object click the "Add..." button. To edit a persistent object's property click the "Edit..." button [1] as seen in Image 10


Image10: Edit the properties of the persistent.

The dialog in Image 11 should appear.


Image11: Dialog to edit a property.

The three text boxes [1] allow to customize the output for the database's associated field ("Storage field name"), the name of the property ("Property name") and the name of the field that is created for the property in the persistent class ("Object field name").

The following example shows what is meant by those values:

C#  VB.NET  
[Persistent("FOO")]
public class Foo
{
    private long _bar; // << Object field name
    
    [Field("BAR")] // << Storage field name
    public long Bar // << Property name
    {
        get { return _bar; }
        set { _bar = value; }
    }
}

The three checkboxes [2] allow to specify the properties of the FieldAttribute.

  • "AllowDBNull" is checked if the property can be null in the database.
  • "Identifier" is checked when the property is an identifier (part of the primary key).
  • "AutoNumber" is checked if the property is an autoincrement value. This applies for example in Microsoft Access if the database field is marked as "AutoIncrement".

The "Property Type" combo box [3] allows to specify the type of the property. Usually the Opf3 Wizard tries to get the type from the database schema. It could happen that sometimes the type is not fetched property. In this cases you may change the type here manually. The length is only enabled if you have choosen the type System.String.

Another thing that may be customized is the "Behaviour during persist". Those two check boxes [4] allow you to exclude the property during inserts oder updates. If you don't want the properties do be updated, just check the "PersistBehaviours.DontUpdate" property. The property will be excluded in any database update of the persistent object.

How to manage the storage's relations?

Image 12 shows the list [1] holding the relations of the database. The Opf3 Wizard only detects automatically one-to-one and one-to-many relations. Many-to-many relations are not detected, because they exist as two one-to-many relations in the database. If you have many-to-many relations in your database, you need to configure them manually in the wizard.


Image12: List of relations found in the database.

The three buttons "Add...", "Edit...", "Remove" [2] in the bottom left allow to add, edit or remove a relation to/from the list. A removed item is no longer updated when the project is loaded again and a load of the schema is done (the diff engine knows that the item has been removed).

In the bottom right corner [3] you find two buttons: "Check all" and "Uncheck all". Those two buttons allow to check or uncheck all relations. An unchecked relation is not equal to a deleted one. It is still updated when doing a second load, but the wizard does not create an output for it. Unchecking is the same as disabling the output for it.

How to add/edit a relation?

To add a relation click the "Add..." button, to edit a relation click the "Edit..." button (see Image 12 [2]) in the bottom left corner of the wizard's main window. The dialog in Image 13 should appear.

General page


Image13: Edit general settings of the relation.

Image 13 shows the "General" page of the relation. The combo box in the top [1] specifies the type of the relation. Opf3 supports one-to-one, one-to-many and many-to-many relations.

The check box in [2] specifies if the relation is created in the parent object. If you uncheck this here, the parent object does not have a relation to its child objects. This feature is very useful because sometimes you don't need one object to have a relation to another (also when specified in the database). Often only one of the two objects needs to have a relation, and the other doesn't. You should always try to minimize the relation between your objects: to much of them confuse the developer, working with the objects.

The "Object(Set)Holder property in parent persistent" text box [2] specifies the name of the property that holds the relation in the parent object:

C#  VB.NET  
[Persistent("FOO")]
public class Foo
{
    private ObjectSetHolder<Bar> _bars = new ObjectSetHolder<Bar>();
    
    public ObjectSet<Bar> Bars // << ObjectSetHolder property in the object.
    {
        get { return _bars.InnerObject; }
    }
}

[3] enables the same functionalities for the child object in the relation. You may specify here if the relation is created in the child persistent and the name of the Object(Set)Holder property in the child persistent.

The combo boxes in "Persistent objects in relation" [4] specify the persistent objects that are part of the relation. If you selected "many-to-many" in [1] the third combobox "Weak persistent" is enabled. You need to specify here the persistent object that maps to the "weak entity" in the database. A "weak entity" is the table in a many-to-many relation that holds only foreign keys to other tables.

Finally the two check boxes in "Behaviour during persist" [5] allow to specify the behaviour of the relation during inserts or updates of the persistent object. If you don't want the relation do be updated, just check the "PersistBehaviours.DontUpdate" property. The relation will be excluded in any database update of the persistent object. The same applies to "PersistBehaviours.DontInsert". The relation wil be excluded in any database insert of the persistent object.

Relations

Relations in Opf3 are always specified this way:

One-to-many and one-to-one
ParentPersistent.PropertyX = ChildPersistent.PropertyY
Many-to-many
ParentPersistent.PropertyX = WeakPersistent.PropertyY and
WeakPersistent.PropertyZ = ChildPersistent.PropertyA


Image14: Edit the related properties of the relation.

Image 14 shows the "Relations" page of the relation. In a one-to-many or one-to-one relation this page allows to specify the related properties between the parent persistent object and the child persistent object. If you are having a "many-to-many" relation you specify here the related properties between the parent persistent object and the weak persistent object.

The main list [1] on the page shows the related properties. We are here in a one-to-many relation: therefore those are the related properties of the parent persistent object and the child persistent object.

The three buttons [2] in the bottom left corner allow to add, edit or remove a related properties pair. Clicking on the "Add..." button opens the windows shown in the Image 15.


Image15: Add/edit a related properties pair.

This dialog allows to select the related properties and add or edit them.

Weak Relations


Image16: Add/edit a weak related properties pair.

Image 16 shows the "Weak Relations" page of the relation. This page is only enabled in a many-to-many relation. It allows to specify the related properties between the weak persistent object and the child persistent object. Apart from that the page behaves as the "Relations" page.

How to create the index based searcher classes?

An index based searcher is a class that searches for persistent objects in the database by using the indexes of the persistent object's database entity. The Opf3 Wizard creates one searcher for each persistent object that is created. The searcher plug-in uses the indexes of the persistent's entity (table or view) to create the search methods.


Image17: Specify the general settings for the searcher classes.

Image 17 shows the general settings that may be specified for the searcher. You can select if the searcher inherits from ObjectSearcher [2] (which is the default behaviour) or if the searcher uses a static "business server" instance to do its searches [3]. When selecting the second option you may also add additional using statements [1] to the searcher class to have the namespace of the "business server" included.


Image18: List of searcher classes that are going to be created for the persistent objects.

The next page (see Image 18) shows all searcher classes [1] that are going to be created for the persistent objects. The "Edit..." button [2] allows to edit the selected searcher. The two buttons "Check all" and "Uncheck all" [3] in the bottom right corner of the window allow to check or uncheck all created searcher. An unchecked searcher is not going to be created.

A click on the "Edit..." button [2] opens the dialog shown in Image 19.


Image19: Edit general settings of the searcher.

This dialog's "General" page allows editing the name [1] of the created searcher class. Image 20 shows the "Methods" page of the dialog.


Image20: Edit methods of the searcher.

The list view [1] in the window shows all methods that are created for the searcher. Each method searches persistent objects by the index in the database. For example "UserSearcher.SearchByEMail" searches all user persistent objects by their e-mail address.

The buttons in the bottom left corner [2] allow to customize the methods of the searcher. The buttons in the bottom right corner [3] check or uncheck all methods. An unchecked method is not created.

Clicking on the "Edit..." or "Add..." button openes the dialog that allows to add/edit a search method. Image 21 shows the dialog that pops up, when clicking on the "Edit..." button.


Image21: Edit one method of the searcher.

You may specify in the dialog the name of the method [1], the return type [2] and the arguments of the method [3]. [4] holds the list of available arguments: Each property of the persistent object may be used as argument.

How to create unit tests for the persistent objects?

The Opf3 Wizard is also able to create test cases for the persistent objects. The tool supports test cases for NUnit and Microsoft Visual Studio 2005. Image 22 shows the page that allows to customize the unit tests created for NUnit (The page for Visual Studio unit tests looks the same).


Image22: Customize unit tests for NUnit.

The text box "File name" [1] allows to customize the file name of the unit tests. "[File]" stands for the file name of the persistent object. If you have for example a persistent file name "User.cs" the default test file name would be "UserTest.cs".

"Class name" [2] allows to specify the class name for the unit test. "[Class]" stands here for the class name of the tested persistent object. E.g.: If you have a persistent class name "User" the default test class name would be "UserTest".

The wizard creates for every property of the persistent object a test method. You may customize the name of those in [3]. "[Method]" stands here for the name of the property that the test is created for. If you have a property with name "ID" in the default test method name would be "IDTest".

The namespace text box [4] allows you to specify a namespace for your tests cases. Usually a namespace with ending ".Tests" should be selected: e.g. Chili.Neutrino.Tests.

"General options" [5] offers additional options for the test cases. By unchecking the different check boxes you may customize the test cases.

How to create interfaces for the persistent objects?

The Opf3 Wizard allows to create for each persistent object also an interface. The interface contains all properties of the persistent object and may be used instead of using the classes. Image 23 shows the list [1] containing the interfaces that are created for the persistent object.


Image23: List of interfaces that are going to be created for the persistent objects.

The "Edit..." button in the bottom left corner [2] allows to edit a selected interface and the two buttons in the bottom right corner [3] allow to check or uncheck all interfaces. An unchecked interface is not created.

When clicking the "Edit..." button the dialog in Image 24 appears. The dialog allows you to change the name for the interface [1].


Image24: Edit an interface.

How to edit the advanced persistent objects' features?

The wizard allows to customize also advanced features for the persistent object (see Image 25). You may mark the persistent objects as sealed [1], which makes deriving from the persistent class impossible. Another option is to mark all properties as virtual [2]. Checking this feature makes it easy to inherit and override properties of the persistent objects.


Image25: Customize the additional data for the persistent object.

The third feature is creating the persistent as two partial classes [3]. The feature creates a partial class with all the persistent definition and an empty partial class. You may put your code in the empty partial class and don't touch the persistent definition. Updating the persistents is made easier by using this feature.


Image26: Customize the interfaces that are implemented by the persistent object.

The next page (see Image 26) allows to specify the interfaces that are implemented by the persistent objects. You may choose to implement the following interfaces: IDynamicExtensible, IObjectNotification, IPopulateHelper or ISelfContainingObject [1] of the Opf3 Framework.

The last interface INotifyPropertyChanged is an interface of the .NET framework and notifies data sensitive controls about an update in a property of the persistent object. If you work with DataGrids and other databound controls you may also implement this interface.

How to edit the final data for the objects?

Image 27 shows the page where you need to enter the final data for the different objects that are going to be created.


Image27: Page with the final data for the objects.

The two text boxes in the top [1] contain the user's name and copyright information for the different objects.

The text box "Namespace for the persistent object" [2] holds the namespace of the persistent objects. If you don't create any persistent objects (in the current run) you need also to enter the namespace of your persistent objects here because it is required by some plug-ins. They often reference the namespace (for example in their "using" directives) of the persistent objects.

The last text box on the page [3] specifies the output directory for the different objects. All plug-ins are going to output their results in the given directory or in a sub directory of it.

How to interpret the output of the object creating process?

Image 28 shows the final output of the Opf3 Wizard. The main list [1] contains the created objects. If an object couldn't be created the list item contains also the exception message for that object.


Image28: List with the final output.

The two indicators [2] in the bottom left corner of the window return how many objects have been created successfully. The button in the bottom right corner allows to open the log file for the creation process. The log contains detailled information on errors.