Eh bien voici ce que j'ai fini par mettre en place comme preuve de concept, juste une poignée de méthodes d'extension, vraiment. Cela repose sur l'objet COM et la mise en œuvre IPersist
ayant une classe RCW dans l'un des PIA chargés dans le AppDomain
courant.
internal static class ExtensionMethods
{
internal static object ConvertToRCW(this object o)
{
var guid = o.GetCLSID();
if (guid != Guid.Empty)
{
return Marshal.CreateWrapperOfType(o, o.GetTypeFromGuid(guid));
}
else
{
return o;
}
}
internal static Guid GetCLSID(this object o)
{
Guid guid = Guid.Empty;
var p = o as IPersist;
if (p != null)
p.GetClassID(out guid);
return guid;
}
internal static Type GetTypeFromGuid(this object o, Guid guid)
{
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
foreach (var assembly in assemblies)
{
var types = assembly.GetLoadableTypes();
foreach (var type in types)
{
if (type.GUID == guid)
return type;
}
}
return o.GetType();
}
internal static IEnumerable<Type> GetLoadableTypes(this Assembly assembly)
{
try
{
return assembly.GetTypes();
}
catch (ReflectionTypeLoadException e)
{
return e.Types.Where(t => t != null);
}
}
}
Utilisé comme ceci:
var point = new ESRI.ArcGIS.Geometry.Point();
point.PutCoords(1, 1);
Console.WriteLine(point.GetType().FullName);
Console.WriteLine(point.Envelope.GetType().FullName);
Console.WriteLine(point.Envelope.ConvertToRCW().GetType().FullName);
Je reçois la sortie suivante:
ESRI.ArcGIS.Geometry.PointClass
System.__ComObject
ESRI.ArcGIS.Geometry.EnvelopeClass
Quel a été le résultat souhaité. Maintenant, pour rendre ce jeu agréable avec LINQPad (mon original question).
Le deuxième paramètre transmis à CreateWrapperOfType doit être défini dans l'espace .NET (avec les attributs ComImport, etc.). Il ne fonctionnera donc pas sans définir ce type (en utilisant C# code, tlbimp ou Reflection Emit) –
J'ai des PIA avec les RCW définis (voir la question connexe pour plus d'informations). – blah238
Oui, cela ne change pas la réponse :-) il est toujours votre travail pour fournir le type, comme il peut y avoir un ensemble infini de types dans l'espace .NET qui définissent l'objet COM correspondant. Donc, si vous avez des PIAs, vous pouvez parcourir toutes les classes dans l'espace de noms PIAs (en utilisant Reflection par exemple), construire un 'Dictionary', et fournir le type de ce dictionnaire quand vous avez le guid. –