我手头有一个IntPtr
到受管理对象IUnknown
的位置,其中受管理对象位于另一个AppDomain中。这意味着指向它的CCW。我想设计一种方法签名,以将其正确返回给其他COM客户端,例如经典ASP。像这样的东西:
[return: MarshalAs(UnmanagedType.IUnknown)]
public IntPtr Resolve(string typeName);
但是,这不起作用。 .NET不够聪明,无法在此处执行正确的操作。该方法作为实际的整数值出现。
我不想返回object
,因为我不想解析实际的托管实例,因为我不想让它尝试在此特定的AppDomain
中加载关联的托管程序集。该IntPtr
与来自不同AppDomain
的托管对象相关联。
[编辑]
一些其他说明:我正在尝试处理从ASP.Net获取的托管COM对象,该对象位于默认域之外的AppDomain
中。通常,当您执行CreateObject("managedobject")
时,最终会在流程的默认AppDomain
内创建实例。相反,我提供了一个代理来解析来自另一个AppDomain的对象。因此,这意味着我的代理驻留在默认域中,但是它的Resolve
方法从另一个域返回一个托管对象,并将其返回给调用COM客户端。
完整用例:我在同一过程中拥有经典的ASP和ASP.Net。我想解析驻留在共同托管两个站点的同一AppDomain中的托管.NET对象。 ASP.Net为每个站点生成一个AppDomain。但是,不受管理的ASP对此一无所知。但是,这是一个托管的IIS管道,因此应该可以使用。
附加说明:我想在ASP.Net站点中拥有一个要解析对象的Autofac容器。
是的,我正在尝试从经典ASP中使用Autofac和DI。疯狂的时代!
结果证明我可以使用它
/// <summary>
/// Resolves an object from the container.
/// </summary>
/// <param name="typeName"></param>
/// <returns></returns>
[return: MarshalAs(UnmanagedType.IUnknown)]
public object Resolve(string typeName)
{
var ptr = (GetProxy() ?? GetGlobalProxy())?.Resolve(typeName) ?? IntPtr.Zero;
if (ptr == IntPtr.Zero)
return null;
// resolve to RCW, which .Net can marshal correctly
var obj = Marshal.GetObjectForIUnknown(ptr);
Marshal.Release(ptr);
return obj;
}
这为远程CCW生成了RCW。可以将其正确地编组为IUnknown。从技术上讲,我认为这是不必要的对象,因为原始的COM对象可以正确接收这些调用,并且我们实际上不需要在RCW前面添加它。但是,这使编组人员感到高兴。
仍在寻找更好的解决方案。
因此,我的用例可行。在Classic ASP中,我可以这样做:
<object runat="server" scope="Application" id="ComponentContext" progid="Cogito.Autofac.Asp.ComponentContextProxy"></object>
后跟Set obj = ComponentContext.Resolve("Cogito.Autofac.Asp.Sample.Objects.ResolvableObject, Cogito.Autofac.Asp.Sample.Objects")
在ASP页上。并从Autofac解析对象。美丽。