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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With