Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting information from an Assembly without loading it

My app has a plug-in structure where it loads dlls (bog standard .NET assemblies) as plug-ins. I have an application wide option to either load those dlls directly from the disk (Assembly.LoadFrom(file)) or to copy the dll into memory first and then load from a byte-array (Assembly.Load(IO.File.ReadAllBytes(file))).

I want to add the option for plug-in developers to choose whether they want to force a specific loading behaviour. I thought I'd use AssemblyAttributes for this and then ReflectionOnly load the dlls to see if the attribute is defined. However I have not been able to get at this information using GetCustomAttributesData because the dlls depend on other assemblies which haven't been reflectiononly loaded. I now find myself in a kafkaesque game of whack-a-mole.

What would be a good way for plug-in developers to communicate with my app before their dlls are loaded for real? Are AssemblyAttributes the way to go, and, if so, how do I make sure the reflectiononly loading never fails?

EDIT:

I referenced Mono.Cecil to iterate over the assembly attributes. First time ever I used Cecil, hope I'm doing it right. Initial tests on my developer machine seem to work.

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
like image 809
David Rutten Avatar asked Aug 10 '26 10:08

David Rutten


1 Answers

Reflection-only load still loads the thing, so once you've done that, it sort of too late to ask the question.

One option would be to perform the reflection-only load in a separate AppDomain, and then return the result back to your main code, and throw away the new AppDomain.

An alternative to using attributes would be to ask plugin developers to include some sort of manifest file (e.g. text or XML) which contains any information or options you require.

like image 92
RobSiklos Avatar answered Aug 14 '26 08:08

RobSiklos



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!