DataCrypt DataCrypt - 7 months ago 15
Vb.net Question

Replace Imports Statement and Load DLL in code to use object?

I currently have applications that use a free NLog logging library (a DLL) which I reference in my VB.NET project (Imports statement, declare it, etc.).

I have written a Class Library (DLL) that contains some common functionality to my applications which also utilizes the free NLog logging library. My issue is that when I upgrade the NLog.dll for my main application, I also need to go and update my Class Library application. I don't want to have to update/re-compile class library each time and would like to pass in the current object or load the NLog assembly dynamically (in-code).

In my class library project, I have something like this:

Imports NLog

Private mLog As Logger

Public ReadOnly Property Log As Logger
Get
If (mLog Is Nothing) Then
mLog = LogManager.GetCurrentClassLogger
End If
Return mLog
End Get
End Property

Later on used as:
Log.Error("Message...")


I was hoping to pass in the NLog object into a function and then somehow load the NLog assembly and declare a variable to use it.

''Imports NLog

Private mLog As Object

Public ReadOnly Property Log As Object
Get
If (mLog Is Nothing) Then
Dim theAssembly As Assembly = Assembly.LoadFrom(AppDomain.CurrentDomain.BaseDirectory & "NLog.dll")
Dim typeLogManager As Type = theAssembly.GetType("NLog.LogManager")
Dim myObj As Object = Activator.CreateInstance(typeLogManager)
mLog = typeLogManager.InvokeMember("GetCurrentClassLogger", BindingFlags.Default Or BindingFlags.InvokeMethod, Nothing, myObj, Nothing)
End If
Return mLog
End Get
End Property


I thought this would create the "CurrentClassLogger" object, but it keeps failing with the error "No parameterless constructor defined for this object." on the line

Dim myObj As Object = Activator.CreateInstance(typeLogManager)


Not sure what I'm doing wrong here or what I'm missing. I would like to be able to create the Logger similar to as if I had referenced (imported) in the NLog assembly. Any help and sample code is greatly appreciated!

Kind Regards

Answer

First get the LogManager type like you already did. Then get the static GetCurrentClassLogger method and invoke it:

Dim typeLogManager As Type = theAssembly.GetType("NLog.LogManager")
Dim currentLoggerMethod As MethodInfo = typeLogManager.GetMethod("GetCurrentClassLogger", Type.EmptyTypes)
mLog = currentLoggerMethod.Invoke(Nothing, Nothing)