Sergey Azarkevich
Sergey Azarkevich

Reputation: 2671

Type.GetType returns null when called via COM interop

I have Assembly A which contains CustomSettings provider MySettingProvider. This assembly created by native process as COM object and then CLR try resolve provider type by name with Type.GetType call.

If I try resolve type directly in startup code of A:

var aqn = typeof(MySettingProvider).AssemblyQualifiedName;
var providerType = Type.GetType(aqn);

this works.

But by some reason Type.GetType called from system assembly:

System.dll!System.Configuration.ApplicationSettingsBase.CreateSetting(System.Reflection.PropertyInfo propInfo) Line 426 C#

returns null

Assembly Qualified name identical in both cases.

If I start assembly A not as COM object but as regular assembly from managed process, then Type.GetType works in both cases: in A startup code and in System.Configuration.ApplicationSettingsBase.

If I add one more nesting level and try create type in assembly B, it is also works.

Some 'pictures' with call stacks:

native.exe
  -> COM interop
    -> A.dll
      -> Type.GetType: OK
      -> B.dll
        -> Type.GetType: OK
      -> System.Configuration.ApplicationSettingsBase
        -> Type.GetType: null

managed.exe
  -> A.dll
    -> Type.GetType: OK
    -> B.dll
      -> Type.GetType: OK
    -> System.Configuration.ApplicationSettingsBase
      -> Type.GetType: OK

Any ideas ?

Upvotes: 2

Views: 168

Answers (1)

Hans Passant
Hans Passant

Reputation: 941397

My crystal ball says that Type.GetType(string) returns null because you haven't done anything to help the CLR find the assembly that contains your MySettingProvider class. Which is required, the CLR doesn't stand much of a chance to find it by itself. Something you can quickly test by yourself by copying the assembly into the same directory as "native.exe" so it is in the probing path.

Which is a wholly inappropriate solution of course, a [ComVisible] assembly doesn't get to choose what kind of app uses it. You need to help by storing any dependency that you have in the GAC. Also the place where your main assembly belongs, the GAC is a good solution for COM's DLL Hell problems. On the user's machine anyway, you can test on your own machine by copying files. You may be able to get AppDomain.AssemblyResolve to work, but you'd need a "global" object like Application to ensure you registered the event handler in a timely matter.

Upvotes: 2

Related Questions