Start up Visual Studio and create a new library project called ChromeExtender. For this demo extender we are using the namespace NexusDB.Test.

Step 1 - Creating the project

netguide_extender_newproject

Note: If you want to use any other .NET language just select a the new library project of your language of choice.

Next we add a reference to the NexusDB.Interop.ServerLink assembly supplied with the NexusDB InterOp pack.

netguide_extender_solutionexplorer

In this demo we will use these namespaces: System, NexusDB.InterOp.Base, NexusDB.InterOp.Interfaces, and NexusDB.InterOp.Extenders.

In the Chrome language the main unit now looks like this

namespace NexusDB.Test;

interface

uses

 System,

 NexusDB.InterOp.Base,

 NexusDB.InterOp.Interfaces,

 NexusDB.InterOp.Extenders;

Step 2 - Implementing the Extender

Now let's look at the actual Extender class. We've already added the reference to the assembly that is implementing the whole interoperation between Win32 and .NET. It also implements a base extender class, which we use as the basis for our extender. So we add a

type

 nxTestExtender = public class(nxBaseExtender)

public

   method InternalInterestedIn(anObject: InxExtendedObject): Boolean; override;

   method RecordModify(aData: InxEventRecordModify): Integer; override;

end;

to our unit. Note that all we need to do is override a couple of methods of the base class to register our interest in certain server-side objects, and then react to certain events.

The first method we look at closer is InternalInterestedIn.

method nxTestExtender.InternalInterestedIn(anObject: InxExtendedObject): Boolean;

require

 anObject <> nil;

begin

 Result := ((anObject.ServerObjectType() = nxObjectType.otCursor) and

           ((anObject.Object as InxCursor).TableName.ToUpper = 'ATEST'));

end;

This method is called for every extendable object that is created on the server. The anObject interface parameter passed in has two methods: ServerObjectType, which returns the type of the server object that was created, and ServerObject, which is another Interface giving us more information about the object. Its interface type depends on the ServerObjectType; for the otCursor (TnxServerCursor) it is an instance of InxCursor, which in turn has a TableName method returning the name of the associated table.

If we want to register interest in a certain object, we need to return True, otherwise False. If we return True, all events applicable for this type of object will be forwarded to our class into one central TriggerEvent method. The base class already implements this method, distributes the events to the virtual callbacks (that we override) and casts the passed Interfaces to their final types. This makes reacting to certain events a matter of simply overriding these methods.

Let's take a look at one of these methods, in this case the RecordModify method which, as the name says, will be called for every updated record.

method nxTestExtender.RecordModify(aData: InxEventRecordModify): Integer;

require

 aData <> nil;

begin

try

   AddDebug('RecordModify: (Before = ' + aData.Before + ')');

   AddDebug('  Table Name: ' + aData.Cursor.TableName);

   AddDebug('  Field Count: ' + aData.Cursor.FieldCount.ToString);

   AddDebug('  New Data: ' + nxExtenderHelpers.PrintFieldData(aData.Cursor, aData.NewData));

   AddDebug('  Old Data: ' + nxExtenderHelpers.PrintFieldData(aData.Cursor, aData.OldData));

except

   on E: Exception do

     AddDebug('*** ERROR: '+E.Message);

end;

 Result := 0;

end;

Again, we get the data passed in as an Interface. Please refer to the InterOp Pack Reference for details.

The AddDebug method is defined in the base class of the extender, which again calls into an interface passed to the setup of our class. It's an easy way to test interoperability between Win32 and .NET. We use it in this simple demo to show the data passed to the RecordModify method.

We also use the static method PrintFieldData  method of the nxEntenderHelpers class, which returns the fields in a Field_1=value, Field_2=value, ... Field_n=value form as string. This is accomplished by accessing the methods of the InxCursor and InxFields interfaces.

Step 3 - Compiling

The source for our extender should now be complete. Compile the library into the same directory as the embedded server application we created above.

Home | Site Contents | Documentation | NexusDB Manual V4 | .NET Guide | Extending the NexusDB Server | Building a NexusDB Server Extender using .NET