Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Do you really need of the a database? Know the XPrevail.

0.00/5 (No votes)
5 Dec 2004 1  
Discuss the prevalence concept and as it can be an ideal alternative to the use of database in some situations. We will know the XPrevail, a open source prevalence layer and as your features can make possible a simple and modern programming.

Sample Image - Know_the_XPrevail.gif

What it is prevalence?

The prevalence concept originally was idealized by the Brazilian Klaus Wuestefeld and materialized in the project Prevayler, an implementation in Java. It is an union of old separately applied concepts already in other scenes.

As I mentioned in the summary, the use of the prevalence is an alternative to the use of database. With it, all the business-objects are persisted in the memory and have guarantee of that they will be recouped faithful in case that has some fall of energy or fails in the application. Amongst the main prevalence use advantages I can cite:

     - The great profit of performance for query's;
     - The drastic reduction of costs of a solution (it eliminates costs of serving pair here the database (the hardware), licenses of the 
       serving software of data base, operational cost of maintenance and etc);
     - Induces a development truily objects oriented (in the my most interesting opinion).

It does not leave to visit the section " What it is?" in the site of XPrevail project.

Key concepts 

To understand the functioning general of the prevalence is important that before let us know some terms comumente used inside of this concept, of this form, let us see to follow the main ones of them.

PrevalenceEngine : One is about an prevalence framework's class, that is responsible for all the execution proceeding, it register and backup of the alterations carried through in the PrevalentSystem . Many times we referenciamos it simply as " engine ". We will see more ahead than the XPrevail  make available four type of different engines , each one with its particularitities. 

PrevalentSystem : A class defined for the user who must to reference all the business objects of the application, or either, the objects that will be persisted. The objects referenceds ones will be serializeds when snapshot will be requested to PrevalenceEngine one. Of this form, any object is of this class will have its lost state. 

Snapshot : The PrevalenceEngine is the process in which serialize all the PrevalentSystem (in the reality we will see more ahead than the XPrevail supports the work with multiples PrevalentSystem 's), such which it is at the moment of the request. This gives to origin a new archive of snapshot, and becomes unnecessary the reading of the archives of log of previous operations. 

Operation : By the original concept considered by the prevalence, all alteration to be carried through in objects kept for a PrevalentSystem must be made through objects of class that implement the IOperation interface defined by framework. These instances are passed to the PrevalenceEngine for register and execution. In the prevayler project the interface equivalent is called Transaction . (to see in manifest more details). 

Prevalence execution flux 

To understand the concept better, I go to describe which now would be the flux of execution of a prevalent application. It imagines that let us have only one business class in one given application, the Client class . We go to the pacings to become this prevalent application.


1. We need to define a class that will keep reference our Client objects , it it will be our PrevalentSystem and it could call Clients .


2. We will have to declare a reference it PrevalenceEngine and to initialize it, moment in which will be demanded the information of which class will be the PrevalentSystem, of course must inform Clients .


3. The initialization of the PrevalentSystem must be requested to the PrevalenceEngine, through the PrevalentSystem property. It will accurately return an instance from the Clients class with an equal state to the one of the last execution (in case that she has had one).


4. As it was mentioned, any alteration in the PrevalentSystem, to prevail is demanded that it is made through objects of class that implement  the IOperation interface . Thus, we can declare two class, a AddClient call and another RemoveClient call , both implementing the IOperation interface . Respectively they would be used to add and to remove objects  Client of the PrevalentSystem. (To the long one of this text we will be able to see what the XPrevail considers for a simpler and intuitive programming, not demanding the creation of these class)


5. To add a client, we now need to create an instance of the AddClient class , passing in its constructor the necessary information the execution of its task. We must then request to the PrevalenceEngine that executes this operation. This will involve the serialization of the AddClient  object later in an archive destined to log of operations and its execution, where of fact the addition of the client will occur.


6. Let us say that after to execute some times item 5, beyond terms also carried through some removals of client, we will have then a PrevalentSystem I contend one definitive amount of Client objects . The archive of log of operations will contain a serialized version of all the objects (that they implement IOperation ) that they had effected alterations in the PrevalentSystem, accurately in the same order where they had occurred.


7. Case in this point occurred an energy feed. Our application would have to be restituted in air, so soon the environment has been re-established. At the moment of the initialization of the PrevalenceEngine, it it will go to read all the generated archives of log of operations. It will deserialize all the objects contained in the archives and will go to execute them again. He attempts against for the detail that the objects kept in this archive are of the AddClient class , not them of the Client class . The PrevalenceEngine is constantly registering the alterations carried through in business objects, not them business objects itself.


8. Having the application directed to air and its recouped previous state, we could generate plus some alterations in the PrevalentSystem and request one snapshot. At this moment the PrevalenceEngine will go to generate a new archive, not one of operations, but a specifically for snapshot. This archive will contain a serialized version of the entire PrevalentSystem, or either, effectively of all the business objects. Let us say that after snapshot, we made plus some alterations in the state of the PrevalentSystem and occurred another feed of energy.


9. When our application to request the initialization of the PrevalenceEngine, it will search for most recent snapshot generated. Of ownership of it, it will deserialize its content and will get a version of the PrevalentSystem. Made this, it will catch all the archives of log of posterior operations to last snapshot and re-will execute all previously the operations in top of the gotten PrevalentSystem. This will result in a PrevalentSystem such which existed before the feed, of the possible optimized form more.

 

Requirements of the prevalence

 

The prevalence possess two required requirements to be taken care of for the business objects that will be persisted, them must be serializables and deterministics. A deterministic object is that one that submitted to one same series of alterations, in one same order, always will result in one same final state. The class that represents the PrevalentSystem, obviously, also needs to be serializable. In .NET the more efficient and simplest form to become a serializable class is through the SerializableAttribute attribute.


The involved concepts in the prevalence are established in such way to execute the tasks of an optimized form, this reflected in questions as:


- To serialize the alterations in business objects, in the place of proper them, this significantly diminishes the amount of space in disk necessary to guarantee the state of the PrevalentSystem.

- Not to have any type of indexation in the generated archives, after all the objective is not to simulate a data base, but yes to eliminate it. Of this form, one concentrated only in the process of serialization and restoration of the objects.

- The restoration of a PrevalentSystem through its snapshot is extremely faster than the backup through log of operations. It is easy to perceive the reason, through one snapshot it deserialize the PrevalentSystem as a whole, directly, already with log of operations, it it needs to deserialize all the objects of operations and to execute them again. Therefore he is recommended to carry through snapshots periodically, but it has care, during snapshot of a PrevalentSystem cannot be modified.

 

One another important detail, as all the objects are kept in memory, to work of efficient form with prevalence are necessary to have memory RAM enough to house all the objects of business of the system.


I wait that they have noticed that covering the described pacings previously we do not have no involved instruction SQL. Positive a collateral effect of the prevalence concept is that we are obliged to face with more seriousness the object oriented concept, therefore will be only with it that we will work. We use our proper programming language to carry through querys, can bring and manipulate the data of any form. 

 

What it is the XPrevail?

 

The XPrevail is a .NET prevalence objects layer, friendly and extended, implemented in Delphi for .NET. The framework is compatible with any language .NET, besides being freeware and opensource. The manifest topic XPrevail brings the reasons for which the XPrevail exists, as well as its differentials front to other implementations of prevalence.

 

Great part of you differentiate them searched for me, front to the others frameworks of prevalence, had been in favor of a more natural programming, providing one framework so transparent and less intromicive how much it was possible. I looked for to leave the model of programming with  the XPrevail in such way that an application was less dependent of it, facilitating the swap of the mechanism of persistence without great efforts.

 

I see the persistence as an isolated aspect of a software, not having to influence significantly in its model, architecture and implementation. This ideology was a constant during the modeling and implementation of the XPrevail. These objectives had taken me to make it some things of different form, besides adding some small features.

 

Amongst the main ones you differentiate brought for the XPrevail I can detach the following ones:

 

PrevalentSystem's multiples

 

The XPrevail brings the MultiSystemsPrevalenceEngine, capable to work with  multiples PrevalentSystem's based in transparent proxy's of NET. This type of engine brings the great advantage not to need to define objects to carry through all the alterations in the PrevalentSystem, these alterations can be made through methods defined in the proper PrevalentSystem. The calls to these methods are intercepted and automatically converted into objects that are, in the traditional way, serialized and executed.

 

It makes possible a good splitting of responsibilities, in mode that each PrevalentSystem keeps operations only on objects logically related. Moreover, we can use the controlling class of the proper system as the PrevalentSystem's, not needing to create a global one involving them.

 

In summary, the use of PrevalentSystem's multiples helps to the terms a friendly and elegant code, more compliant with the good oriented object programming.


Covering on all the business objects

 

The XPrevail introduces, through the ExtremePrevalenceEngine , the possibility to intercept all the solicitations carried through to business objects and automatically to transform them into appropriate objects, to serialize them and to execute them. With this, we can work of full transparent form, having access business objects and modifying them directly, without the intervention of a external class, not even of a PrevalentSystem.

 

This is an important pacing in the process to become the use of the XPrevail friendliest the client code, with some few requirements, will be able to make the prevalence of business objects directly, exactly for alterations carried through in them. This also contributes for a form of more natural programming and less dependent of the XPrevail or the concept of prevalence (It sees in roadmap the intention of the XPrevail in also supporting persistence in relationary data base).


Support to aspects oriented programming - AOP

 

Another well interesting feature brought by the XPrevail is the possibility to use a model of development based on the concepts of the aspects oriented programming, many times referenced simply as AOP. Great part of framework is based on proxy's, in turn, in the interception of code, basic principle of the AOP. Of this form, as I already it came using a similar boarding for communication between proxy's and internal class of framework, it was only question to publish a way it client code to get features of this boarding, so soon I  perceived this potential. 


Engines of framework that they implement the IAspectsSupport interface , currently the MultiSystemsPrevalenceEngine and the ExtremePrevalenceEngine , make avaible half to register and to deregister aspects (any object that implements the IAspect interface ) .


The XPrevail make avaible two implemented aspects, in version preliminary daily pay, that can already freely be used by the client code, is they it TraceAspect and ProfileAspect . Respectively, they are capable to register called the methods in top business objects and to register the times taken for execution of the same ones. This is features extremely useful and powerful, certainly it still will be well developed in the future versions of the XPrevail (to see roadmap).

 

He does not leave to visit the " Manifest" section in the site of XPrevail.


Working with the XPrevail

 

We will now see an full example of use of the ExtremePrevalenceEngine , the main PrevalenceEngine of the XPrevail, in it is where we find the real essence of framework. Before continuing, a tutorial reading of the  Hello Prevalence and Hello Prevalence 2 , in the site of the XPrevail, can sufficiently help the agreement of the example that we will develop here.

 

Defining the object model

 

Before thinking about the persistence we need first to define the model of our business objects. For simplicity questions we go to work with only one business object, People . We will use it stops creating a small application for I register in cadastre of people.


  People = class 
  strict private
    FName: System.String;
    FBirthDate: System.DateTime;
    FEMail: System.String;
  public
    function ToString : String; override;
    procedure set_Name(const Value: System.String);
    procedure set_EMail(const Value: System.String);
    procedure set_NiverDate(const Value: System.DateTime);
    function get_Age: Integer;
    property Name : System.String read FName write set_Name;
    property Age : Integer read get_Age;
    property EMail : System.String read FEMail write set_EMail;
    property BirthDate : System.DateTime read FBirthDate write   set_NiverDate;
    constructor Create(aName : String; aEMail : String; aBirthDate :   DateTime);
  end; 


Soon, this would be the definition standard of our class, however we need to make some alterations in mode that it takes care of the requirements of the prevalence and the ExtremePrevalenceEngine. For this, we will need to make the following modifications:

 

  1. As it was said, the business objects need to be serializables, then we must include the SerializableAttribute attribute in the class.
  2. The business objects, as well as the PrevalentSystem, need to be descending MarshalByRefObject.
  3. So that framework obtains to correctly identify a given business object, it it needs to implement the IObjectID interface, besides being marked with the BusinessObjectClassID attribute.

Carried through the necessary alterations, the interface of our People class is thus:


  [Serializable]

  [BusinessObjectClassID(PeopleClassID)]

  People = class (MarshalByRefObject, IObjectID)

strict private

  FID : System.String;

    FName: System.String;

    FBirthDate: System.DateTime;

    FEMail: System.String;

  public

    function ObjectID : string;

    function ToString : String; override;

    procedure set_Name(const Value: System.String);

    procedure set_EMail(const Value: System.String);

    procedure set_NiverDate(const Value: System.DateTime);

    function get_Age: Integer;

    property Name : System.String read FName write set_Name;

    property Age : Integer read get_Age;

    property EMail : System.String read FEMail write set_EMail;

    property BirthDate : System.DateTime read FBirthDate write   set_NiverDate;

    constructor Create(aID, aName : String; aEMail : String; aBirthDate :   DateTime);

  end;


  The next pacing is to create a class that will be our PrevalentSystem, sees then the definition of the PeopleManager class for this intention.

  [Serializable]

  [PrevalentSystemClassID('{319D4955-4CE8-4443-9010-9BAE12046C24}')]

  PeopleManager = class (MarshalByRefObject, IBusinessObjectFromID)

  strict private

    FPeoples : ArrayList;

  strict protected

    function BusinessObjectFromID(BOClassID, ObjectID: string): TObject;

  public

    function AllPeoples : ArrayList;

    [BusinessObjectExport]

    function get_Peoples(Index: Integer): People;

    property Peoples[Index : Integer] : People read get_Peoples;

    function get_PeopleCount : Integer;

    property PeopleCount : Integer read get_PeopleCount;

    [Operation]

    [BusinessObjectExport]

    function AddPeople(aID, aName : String; aEMail : String; aBirthDate :   DateTime) : People;

    [Operation]

    [RealBusinessObjectRecovery]

    procedure RemovePeople(aPeople : People);

    constructor Create;

  end;

 

Such which a business object class, the PrevalentSystem also needs to descend of MarshalByRefObject and to receive the Serializable attribute (in the truth to be serializable). As the ExtremePrevalenceEngine is a PrevalenceEngine that it supports to work with some PrevalentSystem's, it is necessary that they are marked with the PrevalentSystemClassID attribute, so that framework obtains to identify them correctly. It also notices that the IBusinessObjectFromID interface is implemented by the PeopleManager class, this is necessary only if the PrevalentSystem in question keeps reference the business objects.

 

It observes the use of some attributes decorating methods of the PeopleManager class, let us see now so that it serves each one of them.

 

1.      Operation : It indicates to the XPrevail that the method in question carries through alterations in the state of the PrevalentSystem. In case that a method that modifies the state of the PrevalentSystem is marked with this attribute, the alteration will not prevail.

2.      BusinessObjectExport : It indicates to framework that this method returns an object from business for is of the PrevalentSystem, this form, the XPrevail intercepts this call and returns one proxy for the object in question, in mode that the alterations carried through directly in the object are persisted. It observes that, as in all mechanism of persistence, it fits to the programmer to decide what will be persisted. Alterations in an object of business gotten for a method without this attribute will not be persisted.

3.      RealBusinessObjectRecovery : It indicates to the XPrevail that it must recoup the object from a version duplicate of it (more details in the box to follow).

 

RealBusinessObjectRecovery

The prevalence in general way prohibit that class that implement the IOperation interface (or Transaction in the Prevayler), or either, that they modify the state of a PrevalentSystem has direct reference to a business object. Therefore of this form, the business object will be duplicate and the alteration in question will be given in this version duplicates, this cause sufficient problems. This error is sufficiently common, being considered an error of baptism of the prevalence.

 

Then, the XPrevail does not recommend that this is fact, however not prohibit. It it leaves the option of thus shape you its code, being client of will involve some cost of performance. Being certain of this option, it is enough to mark the method with the RealBusinessObjectRecovery attribute and the XPrevail will take care of so that this does not generate unexpected problems. This will be demonstrated in the example.

 

Soon, now already we have our justifd class to develop our prevalent example. And best, all the persistence code already was practically fact, or either, almost none. It observes that the requirements of the XPrevail are not very intrusive, since attributes and/or implementations of interfaces are decided with adornments through. An eventual decision to remove the XPrevail as persistence mechanism, or to customize software to another mechanism, does not imply in a significant loss of code.

 

Developing a console application

 

We now go to create a console application to illustrate the use of the class that we define. So that the text is not big extensive, I will place only the really excellent stretches of implementation. To have access to the full code it is enough to make download of the applicatory one of example of this article. To compile it, it is essential to lower the XPrevail, you can make this through link http://xprevail.sourceforge.net/en-us/download.htm.

 

The first point to comment as to get an initial instance of our PrevalentSystem and as we will see, it must be requested to the PrevalenceEngine. But for this, we need first to get an instance of proper engine. The code below illustrates all this process:

001. var

002.    Engine : ExtremePrevalenceEngine;

003.    GenKeys : GenerateKeys;

004.    PManager : PeopleManager;

005.

006. begin

007.    Engine := XPrevailFactory.CreateExtremePrevalenceEngine([typeOf(GenerateKeys),

              typeOf(PeopleManager)], Path.Combine(Environment.CurrentDirectory, 'data'));

008.    GenKeys   := Engine.PrevalentSystems[typeOf(GenerateKeys)] as GenerateKeys;

009.    PManager := Engine.PrevalentSystems[typeOf(PeopleManager)] as PeopleManager;

 

010. {�}

011. end.


The lines 002 to 004 contain only the declarations of the references. In line 007 the creation of an instance of the  ExtremePrevalenceEngine class is requested, as we can see, this is made through the XPrevailFactory class. The CreateExtremePrevalenceEngine method requires as first parameter an array of System.Type representing the PrevalentSystem's that will be managed by engine. As the parameter informs the folder where the archives of log of operations and archives of snapshots will be placed.

Certainly you already it perceived that we are using as a PrevalentSystem, represented for the GenerateKeys class. That as the name it suggests, will serve exactly as a generator of ID's for our objects. The definition of this class is very simple and can below be seen:

  [Serializable]

  [PrevalentSystemClassID('{5CFE36DA-9C6A-495F-911B-10CD99374195}')]

  GenerateKeys = class (MarshalByRefObject)

  strict private

    HashKeys : HashTable;

  public

    [Operation]

    function NewKey(ObjectType : System.Type) : Integer;

    constructor Create;

  end;


It assures that an only one for objects of a specified type is generated sequential, can occur of business objects to have equal ID's, since that they are of different types. This is a requirement of the ExtremePrevalenceEngine . It observes that as it does not keep business objects, does not need to implement the IBusinessObjectFromID interface. To follow we can see the implementation of its main method, the NewKey.

function GenerateKeys.NewKey(ObjectType: System.Type): Integer;

var

  KeyID : Integer;

begin

  Monitor.Enter(ObjectType);

  try

    if HashKeys.Contains(ObjectType) then

      begin

        KeyID := Integer(HashKeys.Item[ObjectType]);

        Inc(KeyID);

        HashKeys.Item[ObjectType] := &Object(KeyID);

      end

    else

       begin

        KeyID := 1;

        HashKeys.Add(ObjectType, &Object(KeyID));

      end;

    Result := KeyID;

  finally

    Monitor.Exit(ObjectType);

  end;

end;


Strings 008 and 009 get the instances of our PrevalentSystem's. As the operations of the PeopleManager will use the GenerateKeys , it is important that this last either requested first one. This is made through the PrevalentSystems property, having informed the System.Type of the intended PrevalentSystem. We now go to continue analyzing some stretches keys of the implementation of our applicatory one.

 

Adding a people

 

var

  {...}

  ID : String;

begin

  {...}

    ID := Convert.ToString(GenKeys.NewKey(typeOf(People)));

    PManager.AddPeople(ID, Name, Email, BirthDate);

  {...}

end;

 

Removing a people

 

{...}

    PManager.RemovePeople(PManager.Peoples[ Ind ]);

{...}

 

Editing a people

 

var

  Ind : Integer;

  Pp : People;

  Value : String;

begin

  {...}

    Ind := Convert.ToInt32(Console.ReadLine);

    Pp := PManager.Peoples[ Ind ];

  {...}

    WriteLine('');

    WriteLine('Type new value:');

    Value := Console.ReadLine;

 

    case Ind of

      1 : Pp.Name := Value;

      2 : Pp.EMail := Value;

      3 : Pp.BirthDate := Convert.ToDateTime(Console.ReadLine);

      else begin

        WriteLine('Invalid option, exiting.');

        Exit;

      end;

    end;

  {...}

end;

 

Listing the people

 

var

  Arr : ArrayList;

  I : Integer;

begin

  Console.WriteLine('');

  Arr := PManager.AllPeoples;

  for I := 0 to Arr.Count - 1 do

  begin

    with (Arr[I] as People) do

    begin

      Console.WriteLine('[{0}] {1}', &Object(I), &Object(ToString));

    end;

  end;

  Console.WriteLine('');

end;


Showing the results


As we can see, all the code is surprising simple. Now let us see a little of our application in execution: 

Figure 1. Aperture of the ObjectApp example


Figure 2. Adding a people



Figure 3. Listing the registered in cadastre people

 

Being our application ready we can register in cadastre, modify and exclude people the will, and best, independent of that it occurs, its data will be safe. It carries through these operations some times, requests snapshot's evaluates it the result. You can make tests killing the process or same disconnect the machine, you will see that the data will be kept and recouped in the next execution. Everything this without using a data base!

 

After to carry through some operations, to request one snapshot and later more operations we can see that the XPrevail generated the files as shown in figure 4.

Figure 4. Archives of log of operations and archive of snapshot

 

Supporte to Aspects Oriented Programming - AOP

 

In this article I will only introduce this subject, but it certainly will be boarded in more details in posterior tutorial or articles.

 

One of the excellent features brought for the XPrevail is the support to a programming based on the principles of the Aspects Oriented Programming - AOP. This support is dynamic and extensible, the process of creation of aspects is simple and very powerful. Through it we can have elegant solutions for generation of logs, control of concurrency, profiler, auditorship and etc.

 

The AOP promises to fill a gap not filled by the POO, where the cited example most classic is the generation of log's. In the traditional boarding when we need to generate one log of the execution flux of our applicatory one we finish being obliged to spread code for some class. Code this that is not of the intention of the class.

 

The AOP understands that the generation of log's, as well as diverse other problems - including the persistence, it is aspect of software and it does not have to join the business rules. The implementation of the AOP today still is not something standardized such which the POO, of this form, can find some forms of boardings and philosophies of implementation of this concept.

 

I go to only show now a bit of the potential of this wonder and as you to make use of it through the XPrevail.

 

Using the ProfilerAspect

 

It assumes that let us want to make to profiler of our application to know how much time is delaying the execution of some methods. How you it would make this? Obviously it would open the application source and it would start to distribute measurement codes, clearly. But, let us see as we make this with the XPrevail. For this we will modify only two lines of our applicatory one of test, sees:

 

{...}

  Engine.RegisterAspect(ProfilerAspect.Create(nil, falsifies));

{...}

 

This line registers a new aspect (this already available by the XPrevail) in ours engine. Its constructor asks for two parameters, the first one is one stream for register of the measurements - passing nil it he will emit in the console. As the parameter indicates if it must indiscriminately act on all the methods of the PrevalentSystem's and business objects kept by the Engine.

 

As we pass false it will act only on the methods marked with the MethodProfiler attribute. Then, to test, we go to place this attribute in the PeopleManager.AllPeoples method.

 

{...}

    [ MethodProfiler ]

    function AllPeoples: ArrayList;

{...}

 

Soon, made this it is enough to compile the application and we will execute again. It sees in figure 5 the result.


 

Figure 5. ProfilerAspect in action

 

Frightful? Not, I would say fun. Certainly this is a very powerful feature. As it said previously, it now wanted only to leave this presatation, will have one another tutorial or article approaching in more details the use and development of aspects with the XPrevail.


Current state of the XPrevail project

 

Today the XPrevail is in the version 0.9.4 alpha, improvements and refatorys is being made in it constantly. Although it is a version alpha it already is full functional. To visits the section " Roadmap" of the project site to know where route it goes to be lead.

 

In general lines, it is possible that the XPrevail comes to support persistence in relational data bases, of transparent form. Features as replications, support efficient to transactions and object locking also are foreseen. The objective biggest is that let us can, through the XPrevail, to program prevalent applications, with aspects, fault tolerance and load balance. Also it has support the development of dual applications, would be a type of tolerance to the feeds same for applications statefull.

 

Still I am gradual developing the tutorial documentation of the class, articles and and unit tests. Any aid in this direction, as well as with translation for other languages will be appreciated. The spreading of framework through articles, creation of examples and cases of study will be very well comings.

 

Conclusion

 

Simple, not? It are the object model, you saw much referring code the persistence in our application? Really not. It obtains to calculate how much time already spent inside codifying SQL of its class L ? But for me, most cool it is the sensation of that the persistence does not exist, that we are freely working with objects, without in worrying them about its state, therefore they will prevail.

They do not leave to visit the project site http://xprevail.sourceforge.net and start already to program prevalent applications.

Version 1.1 - 11/21/2004

 

 

FernandoVM is Borland Delphi Certified, speaker of all the editions of the BorCon Brazil. Already it acted as contributor, writer and publisher technician of the ClubeDelphi magazine. He is manager of technology, architect and coordinator of the team of development of the Tactium product, a real-teime distributed solution of CTI/CRM used for more than 90 companies, throughout 14 Brazilian states, in the Softium Inform�tica Ltda. Creator and mantenedor of the XPrevail project, Can be contacted in fernandovm@users.sourceforge.net or http://fernandovm.blogspot.com .

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here