Using .NET and the ADO.NET Managed Provider with Caché
Using the Caché Dynamic Binding
[Back] [Next]
Go to:

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
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:
After the CacheMethodSignature object has been used to call a method, the ReturnValue and Arguments properties can be used to retrieve the results.
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:
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.Person 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.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.Person 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();
Add(), SetProperty()
The following code sets the Person.Name property to the value of valueOfName:
   string valueOfName = "test";
   mtdSignature.Add(valueOfName, false);
   person.SetProperty("Name", mtdSignature);
Clear(), SetReturnType(), GetProperty()
Now the method signature is cleared, the return type is set, and the new value of the Person.Name property is retrieved:
   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);
Accessing an object property
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.SetReturnType(conn, ClientTypeId.tObject);
   person.GetProperty("Home", mtdSignature);
   ICacheObject home = ((CacheObjReturnValue)(mtdSignature.ReturnValue)).Value;

This example calls the StoredProcTest() class method, which is declared as follows in the Sample.Person 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.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:
The following related enumerations are also listed here:
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)
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)
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)
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 )
ClientTypeId 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
ClientObjTypeId Enumeration
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