Using .NET Reverse Proxy Objects
The Native API works together with the Object Gateway for .NET. Reverse proxy objects are .NET objects that allow you to manipulate ObjectScript objects via the Object Gateway. You can use a reverse proxy object to call the target’s instance methods and get or set property values, manipulating the ObjectScript target object as easily as if it were a native .NET object.
This chapter covers the following topics:
Introducing the Object Gateway — provides a brief overview of the Object Gateway.
Creating Reverse Proxy Objects — describes methods used to create reverse proxy objects.
Using IRISObject Methods — demonstrates how reverse proxy objects are used.
IRIS Object Supported Datatypes — describes datatype-specific versions of the reverse proxy methods.
Introducing the Object Gateway
The Object Gateway allows InterSystems IRIS objects and .NET objects to interact freely, using the same connection and working together in the same context (database, session, and transaction). Object Gateway architecture is described in detail in Using the Object Gateway for .NET, but for the purposes of this discussion you can think of it as a simple black box connecting proxy objects on one side to target objects on the other:
The connection is via TCP/IP if InterSystems IRIS and the host VM are on two different machines. If they are on the same machine, the connection can be either TCP/IP or shared memory.
As the diagram shows, a forward proxy object is an ObjectScript proxy for a .NET target object (see “Using Dynamic Object Proxies” in Using the Object Gateway for .NET for details). Forward proxies will be mentioned again later, but the focus of this chapter is how to use a .NET reverse proxy to manipulate an ObjectScript target object.
Creating Reverse Proxy Objects
You can create a reverse proxy object by obtaining the OREF of an ObjectScript class instance (for example, by calling the %New() method of the class) and casting it to IRISObject. The following methods can be used to call ObjectScript class methods and functions:
ADO.IRIS.ClassMethodObject() calls an ObjectScript class method and returns the result as an instance of object.
ADO.IRIS.FunctionObject() calls an ObjectScript function and returns the result as an instance of object.
In either case, if the returned object is a valid OREF, it will be used to generate and return a proxy for the referenced object.
See “Class Method Calls” in the previous chapter for more information on how to call ObjectScript class methods. The following example uses ClassMethodObject() to create a reverse proxy object:
ClassMethodObject() is used to call the %New() method of an ObjectScript class named Demo.Test.
Since the return value of %New() is a valid OREF, ClassMethodObject() creates and returns a proxy for the instance.
In .NET, the proxy is cast to IRISObject, creating reverse proxy object test:
IRISObject test = (IRISObject)iris.ClassMethodObject("Demo.Test","%New");
Variable test is a .NET reverse proxy object for the new instance of Demo.Test. In the following section, test will be used to access methods and properties of the ObjectScript Demo.Test instance.
Using IRISObject Methods
IRISObject provides methods to access the ObjectScript target object. The following example uses Invoke() and InvokeVoid() to call instance methods, and accessors Get() and Set() to get and set a property value.
The example in this section uses reverse proxy object methods to access an ObjectScript class named Demo.Test, which includes declarations for methods initialize() and add(), and property name:
Class Demo.Test Extends %Persistent Method initialize(initialVal As %String) Method add(val1 As %Integer, val2 As %Integer) As %Integer Property name As %String
In the following example, the first line creates a reverse proxy object named test for an instance of Demo.Test. The rest of the code uses proxy object test to access the Demo.Test instance.
// Create an instance of Demo.Test and return a proxy object for it IRISObject test = (IRISObject)iris.ClassMethodObject("Demo.Test","%New"); // instance method test.initialize() is called with one argument, returning nothing. test.InvokeVoid("initialize", 42); // sets a mysterious internal variable to 42 // instance method test.add() is called with two arguments, returning an int value. int sum = test.Invoke("add",2,3); // adds 2 plus 3, returning 5 // The value of property test.name is set and then returned. test.Set("name", "Einstein, Albert"); // sets the property to "Einstein, Albert" String name = test.Get("name"); // returns the new property value
This example used the following IRISObject methods to access methods and properties of the Demo.Test instance:
ClassMethodObject() calls Demo.Test class method %New(), which creates an instance of Demo.Test and returns an IRISObject proxy named test (as described previously in “Creating Reverse Proxy Objects”).
InvokeVoid() invokes the initialize() instance method, which initializes an internal variable but does not return a value.
Invoke() invokes the add() instance method, which accepts two integer arguments and returns the sum as an integer.
Set() sets the name property to a new value.
Get() returns the value of property name.
There are also datatype-specific versions of these methods, as described in the following section.
IRISObject Supported Datatypes
The IRISObject.Set() method accepts any Java object as a property value, including all datatypes supported by IRIS.Set() (see “Class IRIS Supported Datatypes”).
The IRISObject invoke methods support the same set of datatypes as the IRIS classmethod calls (see “Class Method Calls”).
In addition to the generic Invoke() method, IRISObject provides the following type-specific methods: InvokeBool(), InvokeBytes(), InvokeDouble(), InvokeIRISList(), InvokeLong(), InvokeObject(), InvokeString(), and InvokeVoid(). It also provides InvokeStatusCode(), which gets the contents of an ObjectScript %Status return value (see “Catching %Status Error Codes”).
All of the invoke methods take a String argument for methodName plus 0 or more method arguments, which may be any of the following types int?, short?, string, long?, double?, float?, byte, bool?, DateTime?, IRISList?, or IRISObject. If the connection is bidirectional, any Java object can be used as an argument.
Trailing arguments may be omitted in argument lists, either by passing fewer than the full number of arguments, or by passing null for trailing arguments. An exception will be thrown if a non-null argument is passed to the right of a null argument.