I have two libraries, as separate DLL's. These libraries don't ever reference each other directly, but there is a chance that they can exist in the same AppDomain.
This isn't an issue (it seems) until the use of ComImport[...]
conflicts.
library1.file1.cs
namespace AudioSwitcher.AudioApi.CoreAudio.Interfaces
{
[ComImport]
[Guid(ComIIds.DEVICE_ENUMERATOR_CID)] //BCDE0395-E52F-467C-8E3D-C4579291692E
internal class MultimediaDeviceEnumeratorComObject
{
}
}
library2.file2.cs
namespace AudioSwitcher.AudioApi.Hooking.ComObjects
{
[ComImport]
[Guid("BCDE0395-E52F-467C-8E3D-C4579291692E")]
internal class MultimediaDeviceEnumeratorComObject
{
}
}
library2.somefile.cs
public void GetObject()
{
//throws unable to cast exception
var enumerator = new MultimediaDeviceEnumeratorComObject();
}
Exception:
Unable to cast object of type 'AudioSwitcher.AudioApi.CoreAudio.Interfaces.MultimediaDeviceEnumeratorComObject' to type 'AudioSwitcher.AudioApi.Hooking.ComObjects.MultimediaDeviceEnumeratorComObject'.
It seems that the first usage of ComImport
"fixes" itself, and any request to create an object with that CLSID in the future returns that first used type.
This seems like a huge oversight, and could cause unexpected issues when interfacing a third party library from different places in code.
Does anyone know of a way to resolve this issue? I have a work around by creating an unknown instance, and casting it directly to an implemented interface. But it seems hacky.
Activator.CreateInstance(Type.GetTypeFromCLSID(new Guid("BCDE0395-E52F-467C-8E3D-C4579291692E"))) as IMultimediaDeviceEnumerator;
EDIT: Source (if it helps): https://github.com/xenolightning/AudioSwitcher
The current working problem is in the AudioSession branch
I ended up not using ComImport
and creating a ComObject "Factory" instead. Code for said factory is below. It allows loading of the same com type in different namespaces without any conflicts.
internal static class ComObjectFactory
{
public static IMultimediaDeviceEnumerator GetDeviceEnumerator()
{
return Activator.CreateInstance(Type.GetTypeFromCLSID(new Guid(ComIIds.DEVICE_ENUMERATOR_CID))) as IMultimediaDeviceEnumerator;
}
}