- Joined
- Jun 20, 2005
- Messages
- 1
- Reaction score
- 0
I am implementing a component that helps a developer with some localization tasks at design-time, and provides some related features at run-time.
My problem is that in order to do the design-time stuff, I need a reference to EnvDTE or EnvDTE80 (I'm using Whidbey beta 2). However, I can't ship these .dlls and I don't need them at run-time anyway. If I simply add a reference to envdte.dll in my project, then the design-time stuff works, but I also have to ship envdte.dll at run-time; otherwise my component will fail to load.
I tried using late binding. I broke the stuff that used envdte.dll into its own .dll, had my component load it using Assembly.Load() inside a test to see whether it was design-time or not. Then I used reflection to invoke methods out of the .dll. This breaks the dependency, but it has a problem: any objects returned by methods that I'm calling through reflection are actually __COMObject stubs represented with MarshalByRefObject, and I can't use reflection on them successfully. For example, one of my methods in the design-time support .dll returns an EnvDTE.Project. From within my component code I see this as an object (since my component no longer has a reference to EnvDTE and thus is late-bound). I know that the object type should have a property called "UniqueName":
object proj = /*call design-time support dll and return a Project */;
//proj is *not* null here
PropertyInfo pi = proj.GetProperty("UniqueName");
//pi *is* null here, but if I put the same calls in the design-time support dll instead of the component dll, it's not.
I assume that what's happening is that there's an AppDomain boundary between my component and the EnvDTE stuff, and because the actual proj variable is a proxy to the real object in the other AppDomain, I'm not able to use reflection on it?
I wondered if I could just use /delayload on my component dll (that way at run-time the design-time support .dll would never be loaded), but that appears to only apply to C++ projects.
I'm stumped at this point. Any brilliant ideas would be appreciated.
--Daniel
My problem is that in order to do the design-time stuff, I need a reference to EnvDTE or EnvDTE80 (I'm using Whidbey beta 2). However, I can't ship these .dlls and I don't need them at run-time anyway. If I simply add a reference to envdte.dll in my project, then the design-time stuff works, but I also have to ship envdte.dll at run-time; otherwise my component will fail to load.
I tried using late binding. I broke the stuff that used envdte.dll into its own .dll, had my component load it using Assembly.Load() inside a test to see whether it was design-time or not. Then I used reflection to invoke methods out of the .dll. This breaks the dependency, but it has a problem: any objects returned by methods that I'm calling through reflection are actually __COMObject stubs represented with MarshalByRefObject, and I can't use reflection on them successfully. For example, one of my methods in the design-time support .dll returns an EnvDTE.Project. From within my component code I see this as an object (since my component no longer has a reference to EnvDTE and thus is late-bound). I know that the object type should have a property called "UniqueName":
object proj = /*call design-time support dll and return a Project */;
//proj is *not* null here
PropertyInfo pi = proj.GetProperty("UniqueName");
//pi *is* null here, but if I put the same calls in the design-time support dll instead of the component dll, it's not.
I assume that what's happening is that there's an AppDomain boundary between my component and the EnvDTE stuff, and because the actual proj variable is a proxy to the real object in the other AppDomain, I'm not able to use reflection on it?
I wondered if I could just use /delayload on my component dll (that way at run-time the design-time support .dll would never be loaded), but that appears to only apply to C++ projects.
I'm stumped at this point. Any brilliant ideas would be appreciated.
--Daniel