Quick Start

Introduction

In this article you will learn to use Euss. The process is made of a few simple steps:

  • Create you domain model, i.e. the classes you want to store
  • Code the application
  • Configure a simple data store
  • Define the metadata, describing your domain model
  • Execute the application
  • Configure advanced persistence engines, like o/r mapping, caching and remoting

After this turorial, you will be able to choose from AOP, Code Generation and Dynamic Proxies, you will understand what is the metadata for Euss, and how to configure Euss to use different persistence engines like XML, generic SQL, O/R mapping and In Memory Database.

Creating the Domain Model

The domain model is made of a set of .Net classes. In our example we will model two classes: Customer and Order

Here is the class diagram of our model if we had decided to use a case tool:

All classes will be put in the namespace Shop.Domain.

Code Generation

In Euss, Code Generation is the most straighforward way to create an application. Code generation is based on a description of the domain model. This description can have multiple forms, among whom we have XMI files, which are the XML representation of UML diagrams, and Euss domain model files, a simpler and more understandable XML file type.

In a new Visual Studio .Net project:

  • Add a reference to the assembly Evaluant.Uss.dll
  • Right click on the project node and select Add then New Item...
  • In the category named Euss, select Euss Domain Model File
  • Name the file Shop.Domain.xml
  • Click on Add

By default, the newly created file has this content:

<?xml version="1.0" encoding="utf-8" ?>
<?evaluant-application progid="EUSS.GenerationModel"?>
<Model xmlns="http://euss.evaluant.com/schemas/GenerationModel.xsd">
    <!--Sample class description-->
    <Package name="Shop.Domain">
        <!--
        <Class name="HelloWorld">
            <Property name="Message" type="System.String"></Property>
        </Class>
        -->
    </Package>
</Model>

Remove the commented part and add the definition of the Customer and Order classes described previously.

NB: As you type the content of the file you will see that you can benefit from Visual Studio .Net's auto completion.

<?xml version="1.0" encoding="utf-8" ?>
<?evaluant-application progid="EUSS.GenerationModel"?>
<Model xmlns="http://euss.evaluant.com/schemas/GenerationModel.xsd">
    <Package name="Shop.Domain">
    <Class name="Customer">
      <Property name="CompanyName" type="System.String" />
      <Property name="Firstname" type="System.String" />
      <Property name="Lastname" type="System.String" />
    </Class>
    <Class name="Order">
      <Property name="Price" type="System.Single" />
      <Property name="Currency" type="System.String" />
      <Property name="DatePlaced" type="System.DateTime" />
    </Class>
    <Relationship type="composition">
      <Parent name="Customer" role="Buyer" multiplicity="1" />
      <Child name="Order" role="Orders" multiplicity="*" />
    </Relationship>
    </Package>
</Model>

As you save the file, the code generation process is automatically launched. Then you can directly access the classes you just described. Behind the scene, a Visual Studio .Net Custom Tool is used. If you expand the file group from Shop.Domain.xml you will be able to see the generated code.

NB: If you need to add some specific business logic in the generated code, you can use the .Net 2.0 new functionnality named Partial Classes where a class can be made of different files. If you are using the framework 1.1 you can add your own code in predefined locations, which are defined as regions. When the code will be generated again, all those regions will be imported back.

We have finished with the creation of our classes. You can go directly to the section Defining the Metadata

Dynamic Proxies

Dynamic Proxies is a method of wrapping any of your class with a dynamically generated inherited class. This inherited class can have an extended behaviour to implement the needed methods for communicating with the core of Euss. Using this technique you can code you own classes; The aim is generally to remove the dependency between your code and the Euss core. However, there are some rules that you must comply with:

  • Your classes can't be sealed
  • The fields must be protected
  • The relationships must be declared as IList or IList<>
  • The relationship properties must be virtual

You will see these are not so much limitative constrainsts, and that any correct object model can cope with those restrictions.

Here are the classes representing our domain model:

Order.cs

using System;
using System.Collections.Generic;
using System.Text;

namespace Shop.Domain
{
    public class Order
    {
        protected float _price;

        public float Price
        {
            get { return _price; }
            set { _price = value; }
        }

        protected string _currency;

        public string Currency
        {
            get { return _currency; }
            set { _currency = value; }
        }

        protected DateTime _datePlaced;

        public DateTime DatePlaced
        {
            get { return _datePlaced; }
            set { _datePlaced = value; }
        }
    }
}

Customer.cs

using System;
using System.Collections.Generic;
using System.Text;

namespace Shop.Domain
{
    public class Customer
    {
        protected string _companyName;

        public string CompanyName 
        {
            get { return _companyName; }
            set { _companyName = value; }
        }

        protected string _firstname;

        public string Firstname
        {
            get { return _firstname; }
            set { _firstname = value; }
        }

        protected string _lastName;

        public string LastName
        {
            get { return _lastName; }
            set { _lastName = value; }
        }

        protected IList<Order> _orders = new List<Order>();

        public virtual IList<Order> Orders
        {
            get { return _orders; }
            set { _orders = value; }
        }

    }
}

NB: The process of dynamically generating sub classes of your domain classes is done while your application is executing, on the fly. Each time you try to load some objects of a certain type, the code of Euss seeks for a corresponding proxy, and generates it if not found.

We have finished with the creation of our classes. You can go directly to the section Defining the Metadata

Aspect Oriented Programming

Aspect Oriented Programming principles are based on CIL generation. This can be seen as code generation, but at the binary level. Thus the impact on your source code is null, and comes as the model for the generation. Moreover, this is the least contraining technique in Euss towards the definition of your classes.

Behind the scene some new instructions will be inserted just after the compilaton occurs, like methods call, implementation of interfaces, and overrides.

The only constraint of this technique is that you have to define your relationship properties using IList or IList<>. Thus the code you need is defined below:

Order.cs

using System;
using System.Collections.Generic;
using System.Text;

namespace Shop.Domain
{
    public class Order
    {
        private float _price;

        public float Price
        {
            get { return _price; }
            set { _price = value; }
        }

        private string _currency;

        public string Currency
        {
            get { return _currency; }
            set { _currency = value; }
        }

        private DateTime _datePlaced;

        public DateTime DatePlaced
        {
            get { return _datePlaced; }
            set { _datePlaced = value; }
        }
    }
}

Customer.cs

using System;
using System.Collections.Generic;
using System.Text;

namespace Shop.Domain
{
    public class Customer
    {
        private string _companyName;

        public string CompanyName 
        {
            get { return _companyName; }
            set { _companyName = value; }
        }

        private string _firstname;

        public string Firstname
        {
            get { return _firstname; }
            set { _firstname = value; }
        }

        private string _lastName;

        public string LastName
        {
            get { return _lastName; }
            set { _lastName = value; }
        }

        private IList<Order> _orders = new List<Order>();

        public IList<Order> Orders
        {
            get { return _orders; }
            set { _orders = value; }
        }

    }
}

The enhancing phase has to be done after each compilation. This can be done using a command line tool shipping with the installation of Euss. Though, it is also possbile to have this done automatically when using Visual Studio .Net. For this to be done you need to had a Weaving Model File to the project containing the classes you want to enhance. Thus you may decide which one of all you domain classes should be able to persist in an Euss store.

Here are the steps:

  • Right click on the project node and select Add then New Item...
  • In the category named Euss, select Euss Weaving Model
  • Name the file Shop.Domain.Weaving.xml
  • Click on Add

Shop.Domain.Weaving.cs

<?xml version="1.0" encoding="utf-8" ?>
<?evaluant-application progid="EUSS.WeavingModel"?>
<Model xmlns="http://euss.evaluant.com/schemas/WeavingModel.xsd">
  <Class name="Shop.Domain.Customer">
    <Property name="CompanyName" field="_companyName" type="System.String" />
    <Property name="Firstname" field="_firstname" type="System.String" />
    <Property name="LastName" field="_lastName" type="System.String" />
    <Relationship child="Shop.Domain.Order" property="Orders" field="_orders" multiplicity="*" type="aggregation" />
  </Class>
  <Class name="Shop.Domain.Order">
    <Property name="Price" field="_price" type="System.Single" />
    <Property name="Currency" field="_currency" type="System.String" />
    <Property name="DatePlaced" field="datePlaced" type="System.DateTime" />
  </Class>
</Model>

From now on, each time you will compile the project, the enhancing phase will take place. The result of this process is displayed in the output window.

We have finished with the creation of our classes. You can go directly to the section Defining the Metadata

Coding a Sample Application

The sample application will store some Customer and Order object in a repository. Then we will see how to retrieve the objects we stored. With Euss our application will be able to use any type of storage.

Create a new Console Application project name Shop.Application

Creating an Object Service

In Euss, the configuration is loaded once using a ObjectService. The actual configuration will be placed in the file engines.config. It will contain all our repositories' configuration.

Program.cs

ObjectService os = new ObjectService("engines.config");

Instantiating an Object Service

The ObjectService class is the most used one. It represents the actual context of a database transaction. You can create instances by using the previously initialized ObjectService.

ObjectContext oc = os.CreateObjectContext();

Serializing Objects

Now we need some objects to serialize. Whatever the thechnique you choose to define you domain model, this is exactly the same code that you have to type.

Customer c1 = new Customer();
c1.CompanyName = "Walt Disney";
c1.Firstname = "Mickey";
c1.LastName = "Mouse";

Order o1 = new Order();
o1.Price = 123;
o1.Currency = "$";
o1.DatePlaced = new DateTime(2006, 02, 21);

Order o2 = new Order();
o2.Price = 321;
o2.Currency = "$";
o2.DatePlaced = new DateTime(2006, 01, 18);

c1.Orders.Add(o1);
c1.Orders.Add(o2);

Customer c2 = new Customer();
c2.CompanyName = "Dreamworks";
c2.Firstname = "Shrek";
c2.LastName = "Ogre";

Order o3 = new Order();
o3.Price = 10;
o3.Currency = "€";
o3.DatePlaced = new DateTime(2006, 03, 02);

c2.Orders.Add(o3);

And finally the code to serialize our objects.

ObjectContext oc = os.CreateObjectContext();
oc.InitializeRepository();

oc.BeginTransaction();
oc.Serialize(c1);
oc.Serialize(c2);
oc.CommitTransaction();

Be carreful with the use of the method InitializeRepository() as it will actually flush any existing data in your repository. It's a hard initlization. In this example we use this to ensure there is no existing data at the moment we start our application.

Loading Objects

Now we can execute some queries over our repository to check if the objects have been correctly saved.

Console.WriteLine("All Customers");
foreach(Customer c in oc.Load<Customer>(typeof(Customer)))
    Console.WriteLine(c.Firstname);

Console.WriteLine("All Customers whose sum of Orders is more than 100");
foreach(Customer c in oc.Load<Customer>(typeof(Customer), "[ sum(Orders.Price) > 100 ]"))
    Console.WriteLine(c.Firstname);

Console.WriteLine("All Orders from Mickey");
foreach(Order o in oc.Load<Order>(typeof(Customer), "[ Firstname = 'Mickey' ].Orders"))
    Console.WriteLine("{0} {1} - {2}", o.Price, o.Currency, o.DatePlaced);

Console.WriteLine("All Orders from Mickey where the Price is greater than 200");
foreach(Order o in oc.Load<Order>(typeof(Customer), "[ Firstname = 'Mickey' ].Orders[ Price > 200 ]"))
    Console.WriteLine("{0} {1} - {2}", o.Price, o.Currency, o.DatePlaced);

Configuring a Simple Data Store

Euss is based on a flexible provider pattern, resulting to a high flexibility in the choice of the persistence mecanism. Thus you can switch from a simple XML file to a production ready infrastructure involving Cache, O/R Mapping, Distributed systems, simply by changing a configuration file.

As an example we will use a simple XML file. In the last section you will learn to configure other persistence engines.

In the current Visual Studio .Net project:

  • Right click on the project node and select Add then New Item...
  • In the category named Euss, select Euss Engine Configuration File
  • The default filename is engines.config
  • Click on Add

As you can see, by default the file contains the configuration for an XML data store.

<?xml version="1.0" encoding="utf-8"?>
<PersistenceEngines xmlns="http://euss.evaluant.com/schemas/EngineConfiguration.xsd" DefaultEngine="Xml">
    <PersistenceEngine Name="Xml" Factory="Euss.Evaluant.Xml.XmlFactory">
        <FileName>euss.xml</FileName>
    </PersistenceEngine>
</PersistenceEngines>

A configuration file is made of several PersistenceEngine tags. It means that a single file can contain different data store configurations. We provide a Name and a Factory. The name is used to set the default one in the root tag. The factory actually sets which persistence engine has to be used. Inside the provider's tag, there is the actual configuration. For the Xml Persistence Engine we just need to set the FileName property.

NB: If you give a look at the initialization of the ObjectService in the sample application, you will see that engines.config is seeked in the current application's folder. However, as you added the file in the project's folder, in won't be duplicated in the compilation folder. In Visual Studio .Net 2005 there is an option in the file's properties to copy automaticallye this file into the build directory. If you don't check this option, you will have to change the ObjectService's initialization by setting either "..\..\engines.config" or by setting the full path of this file.

Defining the Metadata

In a general manner, metadata are data that describe other data. As the same way in Euss, metadata represent information about the domain model, that is to say all the classes, their properties, and the relationships. Those information can be extracted from many sources, and Euss let you define them by several manners. It is important that you understand how important the metadata are. Without them Euss could not know which type is hidden behind a relation, or if it is an aggregation or a composition for instance.

To set the metadata you must define a particular Metadata tag in the configuration file.

Model Files

The easiest way to define the metadata is to use a Model File. If you used code generation to create your domain classes then you must have an existing model file. However you might have used an XMI file, then you can use a command line application shipping with Euss to generate a model file from this XMI.

If you chose Code Generation as your way to create the domain classes, you just have to change your configuration file like this:

<PersistenceEngine Name="Xml" Factory="Evaluant.Euss.Xml.XmlProvider">
  <FileName>euss.xml</FileName>
  <Metadata Type="model">Shop.Domain.xml</Metadata>
</PersistenceEngine>

Metadata Files

Metadata files have a specific schema letting you provide any metadata in an efficient manner. Euss is able to extract metadata from your assembly, but all of them are generally not present. For instance, when you define a relationship by code (using either dynamic proxies or AOP) you never explain if it is an aggregation or a composition. Also with relationships, there is no way in the .Net 1.1 to set the type of the related objects. Thus, using metadata files you will be able to provide a set of none existing metadata that are mandatory.

To add a metadata file from Visual Studio .Net:

  • Right click on the project node and select Add then New Item...
  • In the category named Euss, select Euss Metadata File
  • Name the file Shop.Domain.Metadata.xml
  • Click on Add

Here is the file you content you should define if you whish was to tell Euss that the relationship between Customer and Order is a composition.

Shop.Domain.Metadata.xml

<?xml version="1.0" encoding="utf-8" ?>
<?evaluant-application progid="EUSS.MetaData"?>
<Model xmlns="http://euss.evaluant.com/schemas/MetaDataModel.xsd">
  <Entity type="Shop:Domain:Customer">
    <Reference name="Orders" type="Shop:Domain:Order" composition="true"/>
  </Entity>  
</Model>

NB: Note that the type are not defined like in C# or VB.Net using dots "." between namespaces. This is because those informations are used at le low level layer of Euss, which handles the namespaces by separating them using colons ":".


					

Then to add those metadata to our persistence engine's configuration, we have to modify the file engines.config as below:

<PersistenceEngine Name="Xml" Factory="Evaluant.Uss.Xml.XmlProvider">
  <FileName>euss.xml</FileName>
  <Metadata Type="metadata">Shop.Domain.Metadata.xml</Metadata>
</PersistenceEngine>

Extracting Assembly Information

An assembly is full of metadata. Indeed, the metadata in Euss are mainly made of class definitions. Thus it should be very easy to extract them from existing assemblies. This one possible way of getting the metadata. However, as we have seen in the previous section, an assembly could not contain all important information. If you need to provide those information directly into your code you can use a set of .Net Attributes specific for this. Thoses attributes are defined in the namespace Evaluant.Uss.ObjectContext.Descriptors.

  • PersistenceProperty(fieldName[, type [, composition]])

Here is an example on how we would use it to describe the relationship between Customer and Order.

private IList<Order> _orders;

[PersistentProperty("_orders", typeof(Order), true)]
public IList<Order> Orders
{
    get { return _orders; }
    set { _orders = value; }
}

Then, to automatically import those information from the domain assembly, we had a Metadata section in our configuratioin file:

<PersistenceEngine Name="Xml" Factory="Evaluant.Uss.Xml.XmlProvider">
  <FileName>euss.xml</FileName>
  <Metadata Type="assembly">Shop.Domain</Metadata>
</PersistenceEngine>

Mixing Them All

The simplest way to define the metadata is to get all the information you can from an existing model file or your assembly, then to create a specific metadata file for those that are not defined in you primary source.

As an example we could mix importing the metadata from an assembly and a metadata file like in the following example:

<PersistenceEngine Name="Xml" Factory="Evaluant.Uss.Xml.XmlProvider">
  <FileName>euss.xml</FileName>
  <Metadata Type="assembly">Shop.Domain</Metadata>
  <Metadata Type="metadata">Shop.Domain.Metadata.xml</Metadata>
</PersistenceEngine>

Executing the Application

Here is the result of the sample application:

All Customers
Shrek
Mickey
All Customers whose sum of Orders is more than 100
Mickey
All Orders from Mickey
123 $ - 21/02/2006 00:00:00
321 $ - 18/01/2006 00:00:00
All Orders from Mickey where the Price is greater than 200
321 $ - 18/01/2006 00:00:00

And if we have a look at the XML file we can see this:

<USS>
  <Entity Type="Shop:Domain:Customer" Id="Shop:Domain:Customer:cdc3aa34-d641-442b-8346-e43278bf41d8">
    <Attribute Name="CompanyName">Walt Disney</Attribute>
    <Attribute Name="Firstname">Mickey</Attribute>
    <Attribute Name="Lastname">Mouse</Attribute>
    <Reference Role="Orders" RefId="Shop:Domain:Order:adbf2411-0468-4ded-b475-48c587cbb7c7" />
    <Reference Role="Orders" RefId="Shop:Domain:Order:c243a6f6-41e7-4fb1-b431-027a98a4be51" />
  </Entity>
  <Entity Type="Shop:Domain:Order" Id="Shop:Domain:Order:adbf2411-0468-4ded-b475-48c587cbb7c7">
    <Attribute Name="Price">123</Attribute>
    <Attribute Name="Currency">$</Attribute>
    <Attribute Name="DatePlaced">632760768000000000</Attribute>
  </Entity>
  <Entity Type="Shop:Domain:Order" Id="Shop:Domain:Order:c243a6f6-41e7-4fb1-b431-027a98a4be51">
    <Attribute Name="Price">321</Attribute>
    <Attribute Name="Currency">$</Attribute>
    <Attribute Name="DatePlaced">632731392000000000</Attribute>
  </Entity>
  <Entity Type="Shop:Domain:Customer" Id="Shop:Domain:Customer:db2a3480-1ddc-4573-b62d-eb5ae5edbb7b">
    <Attribute Name="CompanyName">Dreamworks</Attribute>
    <Attribute Name="Firstname">Shrek</Attribute>
    <Attribute Name="Lastname">Ogre</Attribute>
    <Reference Role="Orders" RefId="Shop:Domain:Order:b82700b0-9ac9-496e-a08d-faa78d685401" />
  </Entity>
  <Entity Type="Shop:Domain:Order" Id="Shop:Domain:Order:b82700b0-9ac9-496e-a08d-faa78d685401">
    <Attribute Name="Price">10</Attribute>
    <Attribute Name="Currency"></Attribute>
    <Attribute Name="DatePlaced">632768544000000000</Attribute>
  </Entity>
</USS>

Configuring the Data Repository

Generic Relational Database

This repository is based on a sql database made of three tables to store Entities, Relationships and Attributes. You don't need to take care about the database design. It can be usefull and time saving for little applications or in order to quicly create prototyping applications.

<?xml version="1.0" encoding="utf-8" ?>
<PersistenceEngines xmlns="http://euss.evaluant.com/schemas/EngineConfiguration.xsd" DefaultEngine="SqlGeneric">
    <PersistenceEngine Name="SqlGeneric" Factory="Evaluant.Uss.Sql.SqlProvider">
        <ConnectionString>Server=.;DataBase=Shop;UID=sa;PWD=</ConnectionString>
        <Metadata Type="model">Shop.Domain.xml</Metadata>
        <Dialect>Evaluant.Uss.SqlMapper.MsSqlDialect</Dialect>
        <Driver>Evaluant.Uss.SqlMapper.MsSqlDriver</Driver>
    </PersistenceEngine>
</PersistenceEngines>

Specific Relational Database

This repository is based on a sql database. The schema of the database can be designed regarding your needs and the domain model. A mapping file defines the way entities are stored. This provider allows migrating or starting a new developpment with an existing database.

<?xml version="1.0" encoding="utf-8" ?>
<PersistenceEngines xmlns="http://euss.evaluant.com/schemas/EngineConfiguration.xsd" DefaultEngine="SqlMapper">
    <PersistenceEngine Name="SqlServerSpecific" Factory="Evaluant.Uss.SqlMapper.SqlMapperProvider">
        <ConnectionString>Server=.;DataBase=Shop;UID=sa;PWD=</ConnectionString>
        <Metadata Type="model">Shop.Domain.xml</Metadata>
        <MappingFileName>Shop.Mapping.Xml</MappingFileName>
        <Dialect>Evaluant.Uss.SqlMapper.MsSqlDialect</Dialect>
        <Driver>Evaluant.Uss.SqlMapper.MsSqlDriver</Driver>        
    </PersistenceEngine>
</PersistenceEngines>

Adding a Cache

A cache can be added on top of any data repository to increase performances. It behaves like a layer between the client application and the repository, sending request only if it is necessary.

<?xml version="1.0" encoding="utf-8" ?>
<PersistenceEngines xmlns="http://euss.evaluant.com/schemas/EngineConfiguration.xsd" DefaultEngine="CacheSql">
    <PersistenceEngine Name="CacheSql" Factory="Evaluant.Uss.Cache.CacheProvider">
        <Delegator>
            <PersistenceEngine Name="SqlMapper" />
        </Delegator>
    </PersistenceEngine>

    <PersistenceEngine Name="SqlServerSpecific" Factory="Evaluant.Uss.SqlMapper.SqlMapperProvider">
        <ConnectionString>Server=.;DataBase=Shop;UID=sa;PWD=</ConnectionString>
        <Metadata Type="model">Shop.Domain.xml</Metadata>
        <MappingFileName>Shop.Mapping.Xml</MappingFileName>
        <Dialect>Evaluant.Uss.SqlMapper.MsSqlDialect</Dialect>
        <Driver>Evaluant.Uss.SqlMapper.MsSqlDriver</Driver>        
    </PersistenceEngine>
</PersistenceEngines>
 

In Memory Database

To get highest performances, you can use the memory provider. All information is loaded into memory. Thus all requests are done in memory without any disk access.

<?xml version="1.0" encoding="utf-8" ?>
<PersistenceEngines xmlns="http://euss.evaluant.com/schemas/EngineConfiguration.xsd" DefaultEngine="VMemory">
    <PersistenceEngine Name="VMemory" Factory="Evaluant.Uss.Memory.MemoryProvider">
        <Metadata Type="model">Shop.Domain.xml</Metadata>
    </PersistenceEngine>
</PersistenceEngines>

In case you provide a back-end persistence engine, it will load all its data during initialization, and then work extremely fast in read mode, while also sending all write requests to the real repository.

<?xml version="1.0" encoding="utf-8" ?>
<PersistenceEngines xmlns="http://euss.evaluant.com/schemas/EngineConfiguration.xsd" DefaultEngine="NVMemory">
    <PersistenceEngine Name="NVMemory" Factory="Evaluant.Uss.Memory.MemoryProvider">
        <Metadata Type="model">Shop.Domain.xml</Metadata>
        <Delegator>
            <PersistenceEngine Name="Xml" />
        </Delegator>
    </PersistenceEngine>

    <PersistenceEngine Name="Xml" Factory="Evaluant.Uss.SqlMapper.XmlProvider">
        <FileName>euss.xml</FileName>
        <Metadata Type="model">Shop.Domain.xml</Metadata>
    </PersistenceEngine>
</PersistenceEngines>
 

Distributed System

With a remoting provider configuration, all clients can share the same persitence engine on the server side. For example, the server application can be configured with a cache engine which will be shared between all clients. This provides a server centric behaviour to any of you repository. EUSS is shiped with a host Console application and a Windows Service making use of this engine. On the client side, the configuration file needs only the location of this service. The real repository is only described on the server side.

<?xml version="1.0" encoding="utf-8" ?>
<PersistenceEngines xmlns="http://euss.evaluant.com/schemas/EngineConfiguration.xsd" DefaultEngine="Remoting">
    <PersistenceEngine Name="Remoting" Factory="Evaluant.Uss.Remoting.RemoteProvider">
        <Host>192.168.1.100</Host>
        <Port>8085</Port>
    </PersistenceEngine>
</PersistenceEngines>
 

Copyright (c) Evaluant