Q:
What can you tell me about the communication and the transfer of the arguments between the host OM and proxy?
A:
I believe currently there is no further documentation on this (btw, the on-line documentation is more current than the documentation included with the SDK so please refer to that; although I do not believe there are any changes for this subject).
From the testing I have done, I believe this is the flow:
Case 1:
this.Something-
string name = this.ActiveDrawing.Name;
1) Add-in => Proxy can pass anything including Generics b/c in same AppDomain
2) Proxy => Host => Proxy call happens through the VSTA.Runtime library and uses the Host[Type,Member]Attributes in the proxy to construct invoke calls using public flags
VSTA.Runtime resolves types (including intrinsic and host types of MBRO and serializable) in HTMP
a. VSTA.Runtime => HTMP resolving types (like parameters and return types)
b. VSTA.Runtime => Host - calls into the host application invoking the method constructed above
c. VSTA.Runtime => HTMP resolves types returned by the host
d. VSTA.Runtime => Proxy returns value if any resolved in the HTMP above
3) Proxy => Add-in passing the transparent proxy (if host type) of the object returned by the VSTA.Runtime
Case 2:
x.Something- no serialized objects (like structs) involved
Drawing d = this.ActiveDrawing; //(1)
string d_name = d.Name; //(2)
The first line (1) is resolved as Case 1 above.
The second line (2) is resolved through VSTA.Runtime and does not hit the proxy
1) Add-in => VSTA.Runtime uses the Host[Type,Member]Attributes in the proxy to construct invoke calls using public flags
2) VSTA.Runtime => Host => VSTA.Runtime
a. VSTA.Runtime => HTMP resolving types (like parameters and return types)
b. VSTA.Runtime => Host - calls into the host application invoking the method constructed above
c. VSTA.Runtime => HTMP resolves types
d. VSTA.Runtime => Proxy returns value if any resolved in the HTMP above
3) VSTA.Runtime => Add-in passing transparent proxy (if host type) of the object
Case 3:
x.Something- serialized object involved
Drawing d = this.ActiveDrawing; //(1)
Color C = Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.Application.CreateColor(
System.Drawing.Color.Aqua.ToArgb()); //(2)
d.BackgroundColor = C; //(3)
The first and second lines are resolved as Case 1 above.
The third line (3)
1) Add-in => proxy re-implementation of the serialized type
2) Add-in => VSTA.Runtime uses the Host[Type,Member]Attributes in the proxy to construct invoke calls using public flags
3) VSTA.Runtime => Host => VSTA.Runtime
a. VSTA.Runtime => HTMP resolving types (like parameters and return types)
b. VSTA.Runtime => Host - calls into the host application invoking the method constructed above
c. VSTA.Runtime => HTMP resolves types
d. VSTA.Runtime => Proxy returns value if any resolved in the HTMP above
4) VSTA.Runtime => Add-in passing transparent proxy (if host type) of the object
Only in cases 1 and 3 do you get an opportunity to manipulate the object going from the Add-In to the Host in the proxy. This can be used in workarounds by exposing only “hostTypeEntryPoints” (which can be renamed to “hostType”) to the add-in, or by using serializable types.
For case 2, you do not have the opportunity to manipulate the object in the proxy (unless there is another workaround). Therefore to pass the object between the host and add-in the type must be resolved in the HTMP. When the VSTA.Runtime calls into the HTMP to resolve a type, it only calls once; therefore, the type must be resolved in the first call. So calls like List<intrinsicType> are okay if you resolve them by returning List<intrinsicType> because once the outer type (List<T>) is translated only the intrinsic type remains. Calls like List<hostType> will only resolve if you add tags, like those below, to the HTMP and types in the proxy. Even with these tags the object you are passing back to the host is a transparent proxy, just like the objects the host passes the add-in. In order to resolve this, your host would need to ability to translate the transparent proxy back into a host type. This could be done in a variety of difficult ways- using the same process as the host passing objects to the add-in in reverse, using custom contracts, having the proxy implement some interface which the host has knowledge of and call into, using information of an intrinsic type like a name or index number, using serialized information, and so on.
Posted
Jun 05 2009, 01:56 PM
by
BillL