Voor een project moet ik dynamisch DLL's zien in te laden. De volgende opzet: er is 1 map aanwezig waar ik DLL's in kan stoppen die ik dynamisch wil inladen / uitvoeren.
Nu kwam ik via deze url op het volgende stuk code:
Tevens heb ik de volgende tips in gedachten gehouden
Mijn code ziet er ongeveer zo uit:
Nu faalt mijn code op regel 15, ik kan de functie niet aanroepen en krijg een NullReferenceException. Toch lijkt er wel een instance gemaakt te zijn, tenminste in Visual Studio bevat ModData een waarde (<> Nothing), maar blijkbaar is er geen instance van de methode?
Iemand enig idee waar het mis kan gaan?
Nu kwam ik via deze url op het volgende stuk code:
Visual Basic .NET:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
| Private Sub loadModules() 'Output txtOutput.AppendText("Loading modules from " + moduleLocation + vbCrLf) 'Assembly to load the file Dim assembly As System.Reflection.Assembly Dim textProcessorModule As apcc.textprocessor.ITextFile 'For each .dll file in the module directory For Each file As String In System.IO.Directory.GetFiles(moduleLocation, "*.dll") 'Load the assembly assembly = System.Reflection.Assembly.LoadFrom(file) 'Loop through each of the assemeblies type For Each fileType As Type In assembly.GetTypes 'If the type is of ITestFile If GetType(apcc.textprocessor.ITextFile).IsAssignableFrom(fileType) Then 'Activate the located module textProcessorModule = CType(Activator.CreateInstance(fileType), apcc.textprocessor.ITextFile) 'Add the activated module to the arraylist textProcessingModules.Add(textProcessorModule) 'Output txtOutput.AppendText("Loaded module: " + textProcessorModule.jobName + " " + "v" + textProcessorModule.moduleVersion + vbCrLf) End If Next Next End Sub |
Tevens heb ik de volgende tips in gedachten gehouden
Mijn code is iets verschillend (ik gebruik andere types), maar het principe is hetzelfde. Volgende probleem doet zich voor: ik probeer op regel 19 een instance te maken (van een object met als type de interface) en dan de enige functie aan te roepen die ik zelf heb gedeclareerd in de interface.I don't think it matters too much whether you use interfaces or abstract classes, but I've seen cases where casting doesn't quite work because the two objects, even though they're the same type, are considered "different" types by the runtime (because they were loaded from different assemblies, or they reference different assemblies).
For this reason I tend to err on the side of interfaces for dynamic loading, but I use abstract classes for implementation. As an example:
IFileFormatter -> BaseFileFormatter -> XmlFileFormatter
This way you use interfaces for the runtime/reflection stuff, but you can still share and make use of the abstract classes when inheriting/implementing the concrete classes. For an example of this in the .NET framework, checkout ICollection and CollectionBase - ICollection is used for the work, CollectionBase is just designed to make inheritance easier.
--- --- --- --- --- --- --- ---
Within my main "File Processor" project I now have the interface "ITextFile" and the abstract class "TextFileProcessor" that implements this interface. I was wondering, what is the best way to access this abstract class from the modules that will inherit it considering that they will all be in different projects.
--- --- --- --- --- --- --- ---
Create a seperate DLL project which contains your interfaces. Reference this project/dll for each implementation.
Mijn code ziet er ongeveer zo uit:
Visual Basic .NET:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| 'Assembly to load the file Dim Assembly As System.Reflection.Assembly Dim ModData As ModDatabase.ModDatabase.IModDatabase Dim ObjType As Type Dim ObjPlugin As Object 'For each .dll file in the module directory For Each file As String In System.IO.Directory.GetFiles(DllDir, "*.dll") Assembly = System.Reflection.Assembly.LoadFrom(file) For Each ObjType In Assembly.GetTypes If GetType(ModDatabase.ModDatabase.IModDatabase).IsAssignableFrom(ObjType) Then ObjPlugin = Activator.CreateInstance(ObjType) ModData = DirectCast(ObjPlugin, ModDatabase.ModDatabase.IModDatabase) ModData.ModifyData(My.Settings.DatabaseConnection) End If Next Next |
Nu faalt mijn code op regel 15, ik kan de functie niet aanroepen en krijg een NullReferenceException. Toch lijkt er wel een instance gemaakt te zijn, tenminste in Visual Studio bevat ModData een waarde (<> Nothing), maar blijkbaar is er geen instance van de methode?
Iemand enig idee waar het mis kan gaan?
Microsoft Windows: A thirty-two bit extension and graphical shell to a sixteen-bit patch to an eight-bit operating system originally coded for a four-bit microprocessor which was written by a two-bit company that can't stand one bit of competition.