What is it?. 1
When to use Ubik. 2
When not to use Ubik. 2
Hello, World! 3
Target System Requirements. 6
Microsoft SQL Server 2000, MSDE, 2005 or 2005 Express. 6
Microsoft .NET Framework 2.0. 6
Running the “Stores and Stock Pricing” Example. 6
Installation. 6
Building Ubik. 7
Configuration. 8
The Server 8
The Ubik Persistence Framework (Ubik) is a kind of
object-relational mapper (ORM) – it sits between an application and a database
to provide storage and retrieval services for the objects used by the
application.
Truly object-oriented application development is still very
difficult to realise. Object-orientation is a collection of intermeshing
concepts, and only when applied in concert do these provide the benefits
promised by OO. Current ORM technologies generally do not support the level of
‘object autonomy’ that a maintainable system requires, and instead either force
the application developers to understand the inner workings of managed objects,
or else severely limit the richness of the object model.
Ubik differs from other similar technologies on these key
points:
- It
allows richer object-orientation with fewer limitations (see appendix ‘Why
another ORM?’)
- Ubik
better supports rich-client applications with interactive functionality,
in addition to request-response web applications
- It
is intended to be used from project commencement, i.e. it has less
flexibility for integration into legacy applications than other mappers,
but because of this can provide more functionality and a cleaner
programming model
- It
uses the only partially-standardised object query language in the .NET
world, OPath
The philosophy behind the project is:
- Rich
object-orientation is the best approach to provide the complexity
management that is required when building a complex enterprise-class
application
- The
object model is the key artifact in an enterprise application: the
database’s primary purpose is to support the object model (additional
schemas such as cubes are the key to good reporting,) and the user
interface will have a shorter lifecycle than the object model as
technologies evolve
Ubik draws heavily on the ideas summarized in Martin
Fowler’s Patterns of Enterprise
Application Architecture. This excellent book is worthwhile reading for
anyone working with enterprise information systems.
Some other currently available ORMs are listed in the
appendix “Other ORMs.”
Ubik is flexible enough to be used in many scenarios, from
desktop rich clients to services to web pages.
It is in desktop applications that it excels, because it
supports long-running applications with data update services that cannot easily
be achieved by ORMs that work directly off of the server database in SQL rather
than through a dedicated server like Ubik’s.
- There
is pre-existing code that must be integrated – i.e. not being built from
scratch. Legacy integration capabilities are scheduled for the 3.0
milestone.
- The
database schema is constrained to particular requirements (i.e. it cannot
be dictated by the object model.) Flexible mapping is scheduled for the
2.0 milestone.
- High-volume
queries are required. Paging queries are scheduled for the 3.0 milestone.
- Lots
of aggregate queries are required, i.e. server-side count/average/sum.
This is scheduled for the 3.0 milestone.
- The
database must be written to by another system that cannot be interfaced
with Ubik. This will likely remain a limitation as it interferes with
Ubik’s data caching and updating mechanism.
A succinct ‘Hello World’ example is difficult to contrive –
the full example ‘Stores and Stock Pricing’ is a better introduction to the
kind of application that can be built on Ubik. A sample from that application
shows the query language, and how client code need not be aware of the
side-effects of methods called on the business objects:
StoresAndStockPricingForm.cs
StockItem
newStockItem;
using (Transaction txn = _session.BeginTransaction())
{
newStockItem = new
StockItem(_session,
StoresAndStockPricingFormResources.NewStockItemName,
_brandGrid.GetSelectedItem<Brand>());
newStockItem.Insert();
newStockItem.ChangeSellingPrice(0M);
txn.Commit();
}
The ChangeSellingPrice() method call appears simple to the applications
programmer, but its implementation changes and creates a variety of associated
price tracking objects. These are all persisted to the database when the
transaction is committed.
Some of the implementation of the StockItem
business object class is shown below:
StockItem.cs
public void ChangeSellingPrice(decimal
sellingPrice)
{
foreach (RetailStore store in
Session.Select<RetailStore>(null))
{
ChangeSellingPrice(store,
sellingPrice);
}
}
public void ChangeSellingPrice(RetailStore
store, decimal sellingPrice)
{
StockItemSellingPrice
currentPrice = GetPriceAt(store);
if
(currentPrice != null)
{
currentPrice.SellingPrice =
sellingPrice;
}
else
{
currentPrice = new StockItemSellingPrice(Session,
this, store,
sellingPrice);
currentPrice.Insert();
}
}
public StockItemSellingPrice GetPriceAt(RetailStore store)
{
IList<StockItemSellingPrice> currentPrice =
Session.Select<StockItemSellingPrice>(
"StockItem
= {" + this.ToString() +
"} && RetailStore = {" + store.ToString() + "}");
if
(currentPrice.Count == 0)
return
null;
else if (currentPrice.Count == 1)
return
currentPrice[0];
else
throw
new ApplicationException(
StockItemSellingPriceResources.MultiplePricesFound);
}
These are the only currently-supported database platforms;
however the vast majority of the framework uses only SQL 92 and should thus be
relatively easy to port.
2005 or 2005 Express is required to run the supplied
example.
MSDE and 2005 Express are both freely available and
redistributable.
Versions 1.0 and 1.1 are not supported – the framework makes
heavy use of features available only in 2.0. A Mono port might be attempted if
it is required.
There is an example included with Ubik that shows some of
its features in a WinForms application. This is
already built, in the examples\StoresAndStockPricing\bin\Debug directory.
The example uses new functionality in SQL Server 2005 to
attach a pre-built database.
Before the example will run, you must update the paths in
the ConnectionString and TaskAssemblyDirectory properties. These
cannot currently contain relative paths.
Once the configuration has been updated, run the
Ubik.Remoting.Server.exe executable – an empty console window should appear if
the launch is successful.
The example client application can then be run – StoresAndStockPricing.Client.exe.
To observe the dynamic nature of Ubik, several instances can be run
side-by-side – all changes will be reflected between the instances, and
concurrent edits made to manufacturer, brand and stock item details will be
detected.
The object model in the example tracks current and
historical pricing of stock items at retail stores, and allows updates to those
prices to be scheduled into the future. It is based on the ARTS retail schema,
freely available at http://nrf-arts.org.
For development purposes (in debug mode,) Ubik does not
itself require installation.
When an application is built with Ubik, the Ubik server
needs to be configured with application-specific details (in its config file)
and installed as a system service.
.NET services are installed using InstallUtil.exe from the
%WINDIR%\Microsoft.NET\Framework\v2.0.50727 directory. To install, pass the
name of the service executable on the command line. Uninstallation is
identical, but with an added /u switch.
The following files are required for a basic Ubik server
installation:
- grammatica-1.4.dll
- Ubik.Engine.dll
- Ubik.Engine.Client.UPath.
Grammatica.dll
- Ubik.Remoting.dll
- Ubik.Remoting.Server.exe
- Ubik.Remoting.Server.exe.config
Additionally, the client files must be included if any
server tasks are deployed which use the object model.
The server footprint will be reduced once Ubik.Engine is
split into shared, client and server components.
A basic client installation requires:
- grammatica-1.4.dll
- Ubik.Engine.dll
- Ubik.Engine.Client.UPath.Grammatica.dll
- Ubik.Remoting.dll
- Ubik.Remoting.Client.dll
The .NET 2.0 SDK or Visual Studio 2005 (Express) is required
to build Ubik. Ubik.sln in the ubik\src\ directory is the only solution that must be built.
Output is to the ubik\bin\Debug and ubik\bin\Release directories.
Currently, an installation of the Java VM is required to
build the Ubik.Engine.Client.UPath.Grammatica project.
Server configuration is done in
Ubik.Remoting.Server.exe.config.
ConnectionString
A connection
string for the database, suitable for ADO.NET.
MappingFile
The full path and filename of the
XML mapping file for the model.
TaskAssemblyDirectory
The full path of a directory to
search for assemblies containing server plug-ins, as described in Server Tasks below.
Client configuration is programmatic – see the constructor
of the Session class for
requirements.
The only connection type currently supported is .NET
Remoting via TCP. The port used and the service name are configurable in the
server’s config file.