You may be asking, "Is this proxy layer stuff really necessary? Why do I have to generate proxy types for all my Object Model objects?" And, "I noticed that System Types like string do not seem to require proxy types, they just work, why is that?"
The short answer is:
VSTA requires a proxy to pass non-intrinsic types between the host and addin. VSTA’s proxied types provide version independence, process isolation, and security between the host and the addin.
Now, I’ll elaborate on each of these issues and why you need to be concerned about them:
Type Version Independence
It is possible to create your own addin model using reflection. It is even possible for the host and the addin to agree upon types (like MyObjectModel.Project) to use. But then you will start getting into versioning issues. In .NET, two different versions of a Type are technically different types. If I write an addin to your version 1 types, it won’t work with the same but newer versioned v2 types – the system regards them as different types. There are hoops you can jump through to work around this dilemma using config files and binding redirects, but that adds a level of complexity you don’t want to deal with. VSTA’s “Managed Add-in Framework” provides a standard way for your application and add-in assemblies to version independently.
Unloading the Add-in (process isolation & security)
What if an addin misbehaves and you want to get rid of it? Win32 had the function, 'UnloadLibrary', but in .NET you can’t directly unload an assembly (This has to do with the garbage collection system). The closest you can get is to create a separate AppDomain for the addin, and when it misbehaves – or you just want to unload it for any reason – you can unload the addin’s AppDomain, which unloads everything in it. But, if you want to communicate with that addin – or want it to communicate with you (with the host), everything that goes through the communication layer must be marshalled across the AppDomain boundary. This is accomplished by .Net remoting. In .NET remoting, the transitive closure of all of the types used to communicate (including even internal and private types if objects are copied) requires them to be either serializable or derived from System.MarshalByRefObject. That’s very heavy lifting to do for the Host author and the add-in authors. Thankfully, VSTA’s “Managed Add-in Framework” includes ProxyGen to provide a standard way for your application and add-in assemblies to safely communicate across the AppDomain boundary. The task of unloading and loading addins is also simplified by VSTA’s Add-in Manager.
AppDomain loading (process isolation and .Net Security)
.NET provides a rich security model. There is no better application of security than addins – addins can come from anywhere and you have no idea whether to trust them necessarily. But in order to load an addin in a different security profile than the host application, you need to isolate it – either in another AppDomain or even another process. That gets you back to the marshalling restrictions solved by ProxyGen (see above). And, VSTA’s Add-in Manager provides an add-in collection, and add-in loading methods to establish different levels of isolation and security for addins.
Proxy for Arbitrary Types (security):
A secure proxy layer must provide transitive closure (ie: all types defined within the addin are independent of the types defined in the application). The proxy cannot safely pass through an object derived from System.Object (like MyObjectModel.Project). Exposing such an object is illegal because an object derived from System.Object can represent arbitrary types that may not be accounted for in the closed system. At best passing an arbitrary object or type across the AppDomain boundary will simply fail -- the type won't be visible to the host AppDomain and fail to load. At worst it can be an elevation of privilege security hole. If a malicious addin can cause an arbitrary type to be loaded in a less restricted AppDomain (like your host application), the addin can use static constructors and initializers and run arbitrary, perhaps malicious, code. VSTA’s proxygen generates contracts based on System.Addin.Contract for each object in your Object model. Contracts provide type-safe communication across AppDomain and Process boundaries.
More general and in-depth discussion is available from MS authors.
Jul 31 2006, 01:03 PM