Using the Caché Dynamic Binding
The Caché dynamic binding allows an application to access Caché objects on the server without first generating proxy classes (described in “Using the Caché Object Binding for .NET”). Instead, a dynamic proxy class, CacheObject, can be created at runtime and used to access properties and call methods by name. Argument values and return types are specified by creating instances of the CacheMethodSignature class.
The dynamic binding can be useful for writing generic tools, and can be used as an alternative to regenerating proxy classes whenever a Caché class changes on the server.
This chapter covers the following topics:
-
Using Dynamic Objects — an overview of how to use the CacheObject and CacheMethodSignature classes.
-
Example: Accessing Sample.Person — a simple demonstration of how the dynamic binding is used.
-
CacheMethodSignature Methods and Properties — A quick reference to the CacheMethodSignature class.
Using Dynamic Objects
The examples in this chapter assume that a connection to the database has already been established through a CacheConnection object named conn (see “Connecting to the Caché Database” for more information about CacheConnection). Before dynamic objects can be used, the connection object's DynamicMode property must be set to true:
conn.DynamicMode = true;
A new InterSystems.Data.CacheTypes.CacheObject can be created with a statement such as the following:
CacheObject dynamicObj = new CacheObject(conn, className);
where conn is an open CacheConnection object, and className is a string containing the complete name of the class to be accessed.
Using Method Signature Objects
Before you can use a CacheObject instance to call a method, you must create a CacheMethodSignature object. The method signature object is used to specify the values of any arguments that are to be passed to the method, and the datatype of the method return value.
Use the GetMtdSignature() method of the connection object to create a CacheMethodSignature object:
CacheMethodSignature mtdSignature = conn.GetMtdSignature()
The Add() and SetReturnType() methods of the CacheMethodSignature object are used to define the signature:
-
Use the Add() method to specify the values that will be passed as arguments to the method. Call Add() once for each argument to be passed. The method is called as follows:
mtdSignature.Add(value, isByRef);
where value is a value of the appropriate type, and isByRef is a boolean that specifies whether or not the argument is passed by reference.
-
If the method returns a value, use the SetReturnType() method to specify the return type:
SetReturnType(conn, typeId)
where typeId is one of the constants of the ClientTypeId enumeration.
After the CacheMethodSignature object has been used to call a method, the ReturnValue and Arguments properties can be used to retrieve the results.
-
The ReturnValue property will contain a value of the type specified by SetReturnType().
-
The Arguments property will contain an array with one element for each argument specified by Add(). Each element contains the current value of an argument (including arguments passed by reference).
A method signature object can be used for more than one call. Use the Clear() method to reinitialize the object before using Add() and SetReturnType() again to define the new signature.
Calling Methods
The RunMethod() and RunClassMethod() methods of CacheObject are used to make method calls:
-
For an instance method, the call is:
dynamicObj.RunMethod(methodName, mtdSignature);
-
For a class method, the call is:
CacheObject.RunClassMethod(conn, className, methodName, mtdSignature);
After the method has been called, any returned values can be retrieved from the Arguments and ReturnValue properties of the CacheMethodSignature object (as described in “Using Method Signature Objects”). The returned values must be cast to the appropriate type for the container object. For example the following line gets an integer return value and casts it to class CacheIntReturnValue:
long? mtdRes = ((CacheIntReturnValue)(mtdSignature.ReturnValue)).Value;
The following line accesses the Arguments array to retrieve the current value of a string argument passed by reference, and casts it to class CacheStringArgument:
response = ((CacheStringArgument)(mtdSignature.Arguments[1])).Value;
A complete description of the available Cache(type)Argument and Cache(type)ReturnValue classes can be found in the InterSystems.Data.CacheTypes namespace section of the Caché .NET Help File.
Accessing Properties
CacheMethodSignature objects are also used to specify property signatures. Once the signature has been specified, the GetProperty() and SetProperty() methods of the CacheObject object can be used to access the property value. For example, the following code specifies a signature that will be used for the Name property of a Sample.PersonOpens in a new tab object, and then sets the property to the specified value:
CacheMethodSignature mtdSignature = conn.GetMtdSignature();
string value = "Smith, Wilbur"
mtdSignature.Add(value, false);
string propertyName = "Name"
person.SetProperty(propertyName, mtdSignature);
The following code redefines the method signature, and then retrieves the value of the property:
mtdSignature.Clear();
mtdSignature.SetReturnType(conn, ClientTypeId.tString);
person.GetProperty(propertyName, mtdSignature);
string newName = ((CacheStringReturnValue)(mtdSignature.ReturnValue)).Value;
Example: Accessing Sample.Person
This section provides sample code that uses the dynamic interface to access a Sample.PersonOpens in a new tab object.
The following code creates the CacheObject and CacheMethodSignature objects used by these examples:
CacheObject person = new CacheObject(conn, "Sample.Person");
CacheMethodSignature mtdSignature = conn.GetMtdSignature();
The following code sets the Person.Name property to the value of valueOfName:
string valueOfName = "test";
mtdSignature.Add(valueOfName, false);
person.SetProperty("Name", mtdSignature);
Now the method signature is cleared, the return type is set, and the new value of the Person.Name property is retrieved:
mtdSignature.Clear();
mtdSignature.SetReturnType(conn, ClientTypeId.tString);
person.GetProperty("Name", mtdSignature);
string returnedNameValue = ((CacheStringReturnValue)(mtdSignature.ReturnValue)).Value;
The .NET TestTools.UnitTesting.Assert class is used to compare the property value to the value in the original variable.
Assert.AreEqual(valueOfName, returnedNameValue);
The following code gets the Person.Home object property, tests the object to see if it is connected, then closes the Person object and tests to see if the Person.Home object has been disconnected.
mtdSignature.Clear();
mtdSignature.SetReturnType(conn, ClientTypeId.tObject);
person.GetProperty("Home", mtdSignature);
ICacheObject home = ((CacheObjReturnValue)(mtdSignature.ReturnValue)).Value;
Assert.IsTrue(home.IsConnected);
person.Close();
Assert.IsFalse(home.IsConnected);
This example calls the StoredProcTest() class method, which is declared as follows in the Sample.PersonOpens in a new tab server class:
classmethod StoredProcTest(name As %String, ByRef response As %String) as %Integer
StoredProcTest() concatenates two copies of name and returns the resulting string in response. It always sets the return value of the method to 29.
The following code sets the signature values and return type for the method:
string nameValue = "test";
string responseValue = "";
mtdSignature.Clear();
mtdSignature.Add(nameValue, false);
mtdSignature.Add(responseValue, true);
mtdSignature.SetReturnType(conn, ClientTypeId.tInt);
Now the method is called, and the results are retrieved and tested:
CacheObject.RunClassMethod(conn, "Sample.Person", "StoredProcTest", mtdSignature)
responseValue = ((CacheStringArgument)(mtdSignature.Arguments[1])).Value;
string expectedValue = nameValue + "||" + nameValue;
Assert.AreEqual(responseValue, expectedValue);
long? returnValue = ((CacheIntReturnValue)(mtdSignature.ReturnValue)).Value;
Assert.AreEqual(returnValue, 29);
CacheMethodSignature Methods and Properties
This section provides a quick overview of the CacheMethodSignature class. It is not intended to be your primary reference for the class, and therefore omits some items (such as methods inherited from System.Object) that are not used in this chapter.
For the most complete and up to date information on this class and related enumerations, refer to the entry in the Caché .NET Help File.
The CacheMethodSignature class provides the following methods and properties:
-
Add() — Specifies an argument value to be added to the method signature.
-
Arguments — Field containing an array of method argument values.
-
Clear() — Initializes this instance by deleting any previously specified argument values and method return settings.
-
Get() — Gets the value of the argument at the specified index.
-
ReturnValue — Field containing the method return value.
-
SetColnReturnType() — Sets the method return type if a collection is to be returned.
-
SetReturnType() — Sets the method return type.
The following related enumerations are also listed here:
-
ClientTypeId Enumeration
-
ClientObjTypeId Enumeration
Adds the specified argument value to the method signature. This method has the following overloads:
public void Add(Object arg, CacheConnection conn, Type argType, ClientTypeId typeId, bool byRef)
public void Add(ICacheObject arg, CacheConnection conn, Type argType, bool byRef)
public void Add(CacheStatus arg, CacheConnection conn, bool byRef)
public void Add(CacheSysList arg, CacheConnection conn, bool byRef)
public void Add(CacheDate arg, int typeId, bool byRef)
public void Add(Nullable<(long> arg, bool byRef)
public void Add(Nullable<double> arg, bool byRef)
public void Add(Nullable<DateTime> arg, bool byRef)
public void Add(Nullable<bool> arg, bool byRef)
public void Add(Nullable<decimal> arg, bool byRef)
public void Add(byte[] arg, bool byRef)
public void Add(string arg, bool byRef)
public void Add(CacheTime arg, bool byRef)
-
arg (various data types) — An argument value.
-
conn (CacheConnection) — The connection object.
-
argType (Type) — The argument type.
-
typeId (ClientTypeId) — if arg is an object, specifies the object type as a constant from the ClientTypeId enumeration.
-
byRef (Boolean) — If set to true, the argument is passed by reference.
Field containing an array of currently defined method arguments.
public ArrayList Arguments
Initializes this instance by deleting any previously specified argument values and method return settings.
public void Clear()
Gets the argument at the specified index. This method has the following overloads:
public void Get(int idx, out ICacheObject arg)
public void Get(int idx, out Nullable<long> arg)
public void Get(int idx, out Nullable<double> arg)
public void Get(int idx, out Byte[] arg)
public void Get(int idx, out String arg)
public void Get(int idx, out CacheStatus arg)
public void Get(int idx, out CacheTime arg)
public void Get(int idx, out CacheDate arg)
public void Get(int idx, out Nullable<DateTime> arg)
public void Get(int idx, out Nullable<bool> arg)
public void Get(int idx, out Nullable<decimal> arg)
public void Get(int idx, out CacheSysList arg)
-
idx (Int32) — The index specifying which argument to return.
-
arg (various data types) — The argument to be returned.
Field containing a Server method return value.
public CacheReturnValue ReturnValue
Sets the method return type if a collection is to be returned.
public void SetColnReturnType(CacheConnection conn, ClientObjTypeId objTypeId, ClientTypeId colnTypeId)
-
conn (CacheConnection) — The connection object.
-
objTypeId (ClientObjTypeId) — The data type id for the collection elements (from the ClientObjTypeId enumeration).
-
colnTypeId (ClientTypeId) — The collection type id (from the ClientTypeId enumeration).
Sets the method return type. This method has the following overloads:
public void SetReturnType(CacheConnection conn, int typeId)
public void SetReturnType(CacheConnection conn, ClientTypeId typeId)
public void SetReturnType(CacheConnection conn, Type clientType)
public void SetReturnType(CacheConnection conn, int objTypeId , int colnTypeId )
-
conn (CacheConnection) — The connection object.
-
typeId (Int32 or ClientTypeId) — The type of the return value, specified as either an integer or a constant from the ClientTypeId enumeration.
-
clientType (System.Type) — The type of the return value, specified as a type declaration.
-
objTypeId (Int32) — If the return value is a collection, specifies the data type id for the collection elements (see the ClientTypeId enumeration).
-
colnTypeId (Int32) — If the return value is a collection, specifies the collection type (see the ClientObjTypeId enumeration).
The InterSystems.Data.CacheTypes.ClientTypeId enumeration includes the following values:
tVoid = -1
tObject = 0
tInt = 1
tDouble = 2
tBinary = 3
tString = 4
tStatus = 5
tTime = 6
tDate = 7
tTimeStamp = 8
tBool = 9
tCurrency = 10
tList = 11
tLongString = 12
tLongBinary = 13
tDecimal = 14
tMVDate = 15
The InterSystems.Data.CacheTypes.ClientObjTypeId enumeration includes the following values:
tUnknown = 0
tListOfDT = 1
tArrayOfDT = 2
tListOfObj = 3
tArrayOfObj = 4
tRelationship = 5
tBinStream = 6
tCharStream = 7