2013-03-12 55 views
3

我的应用程序具有插件结构,它将dll(bog标准.NET程序集)加载为插件。我有一个应用程序范围选项,可以直接从磁盘加载这些dll(Assembly.LoadFrom(file)),也可以先将dll复制到内存中,然后从字节数组(Assembly.Load(IO.File.ReadAllBytes(file)))加载。从程序集中获取信息而不加载它

我想为插件开发人员添加选项,以选择他们是否要强制执行特定的加载行为。我认为我会为此使用AssemblyAttributes,然后ReflectionOnly加载dll以查看属性是否已定义。然而,我一直无法使用GetCustomAttributesData获取这些信息,因为dll依赖于尚未反射加载的其他程序集。现在我发现自己在一场咔嗒咔嗒的卡菲卡式的比赛中。

插件开发人员在真正加载dll之前与我的应用进行通信的好方法是什么? AssemblyAttributes的路要走,如果是的话,我如何确保反射加载永远不会失败?

编辑:

我引用Mono.Cecil能遍历组件属性。有史以来第一次使用塞西尔,希望我做对了。我的开发人员机器上的初始测试似乎工作。

Private Function ExtractAssemblyLoadBehaviour(ByVal file As String) As GH_LoadingBehaviour 
    Try 
    If (Not IO.File.Exists(file)) Then Return GH_LoadingBehaviour.ApplicationDefault 

    Dim assembly As AssemblyDefinition = AssemblyDefinition.ReadAssembly(file) 
    If (assembly Is Nothing) Then Return GH_LoadingBehaviour.ApplicationDefault 

    Dim attributes As Collection(Of CustomAttribute) = assembly.CustomAttributes 
    If (attributes Is Nothing) Then Return GH_LoadingBehaviour.ApplicationDefault 
    For Each Attribute As CustomAttribute In attributes 
     Dim type As TypeReference = Attribute.AttributeType 
     If (type.FullName.Contains("GH_CoffLoadingAttribute")) Then Return GH_LoadingBehaviour.ForceCOFF 
     If (type.FullName.Contains("GH_DirectLoadingAttribute")) Then Return GH_LoadingBehaviour.ForceDirect 
    Next 

    Return GH_LoadingBehaviour.ApplicationDefault 
    Catch ex As Exception 
    Return GH_LoadingBehaviour.ApplicationDefault 
    End Try 
End Function 
+0

为什么你提供两种选择?只是好奇... – Jobo 2013-03-12 18:10:16

+0

这是主要的遗产在这一点上。我希望能够从远程位置加载dll,并且出于某种原因需要从磁盘加载某些dll。我期待删除这个作为一个选项,并根据每个dll的基础上决定什么是最好的,但我希望我的开发人员对发生的事情保持一定的控制。 – 2013-03-12 20:16:56

回答

1

只有反射的负载仍然会加载这个东西,所以一旦你这样做了,提出这个问题就太迟了。

一种选择是在单独的AppDomain中执行仅反射负载,然后将结果返回给主代码,并扔掉新的AppDomain。

使用属性的替代方法是要求插件开发人员包含某种清单文件(例如文本或XML),其中包含您需要的任何信息或选项。