[Solved] Loading and using a .NET library?


#1

So, I was wondering if there is a way to load and use a .NET library on the server. I ask this because I want to set up a connection to a MongoDB server to store some data.

What I’ve tried:
I’ve downloaded the driver files from here and have put them into a folder on the server. I’ve then tried the following:

local reflection = clr.System.Reflection
-- Load the mongodb drivers
reflection.Assembly.LoadFrom("resources/test/lib/mongo/MongoDB.Driver.dll")

client = clr.MongoDB.Driver.MongoClient( connectionString )

However, I get a “Object is nil” error on the last line. I’ve managed to figure out that “MongoClient” isn’t a class that can be called but, the documentation differs.

Any help would be appreciated :slight_smile:

Note: I can use the MySQL library that came with essential so, I figure that it must be something to do with the library itself. Does it need a specific function or does it need to be compiled for a specific system?


#2

In some cases you might have to dofile another Lua file after loading the assembly.

See also https://github.com/neolithos/neolua/blob/master/doc/05_01_clr.md


#3

Thanks :slight_smile:

Is there anything in particular that needs doing in the Lua file called through dofile (at the minute i’m just printing a couple of messages)? I’ve tried creating the MongoClient in it but, I get the same error.

I’ve also tried to create the client by doing the code below (as pointed out at the link provided)

const MongoClient typeof clr.MongoDB.Driver.MongoClient -- Also tried just "MongoDB.Driver.MongoClient"
print("MongoClient: " .. MongoClient)
local client = MongoClient(connectionString)
print("created client")

However, I end up with the same error (Object is nil):


#4

It might be overload resolution isn’t working - can you try making connectionString explicitly a string variable, like such?

local connectionString: string = "uh"

#5

Tried it… It didn’t work :frowning:

const MongoClient typeof MongoDB.Driver.MongoClient
print("MongoClient: " .. MongoClient)
local connString : string = "mongodb://localhost:27017"
local client = MongoClient(connString)
print("created client")

I’ve also tried calling the default constructor (without a string) but, still get the error.

Edit: I’ve also tried to specify the overload operator by doing

local mongoClient = clr.MongoDB.Driver.MongoClient[clr.System.String]
print("MongoClient: " .. MongoClient)
local connString : string = "mongodb://localhost:27017"
local client = mongoClient(connString)
print("created client")

#6

What’s the full stack trace you end up getting?


#7

With the current code:

    local assembly = reflection.Assembly.LoadFrom("resources/login_test/lib/mongo/MongoDB.Driver.dll")
    dofile("resources/login_test/lib/empty.lua")
    
    local mongoClient = clr.MongoDB.Driver.MongoClient[clr.System.String]
    print("MongoClient: " .. clr.MongoDB.Driver.MongoClient:GetType())
    local connString : string = "mongodb://localhost:27017"
    local client = mongoClient(connString)
    print("created client")

Edit: I get the same error with the other implementations too


#8

The MongoDB client library is strange - it appears to depend on System.Runtime.InteropServices.RuntimeInformation.dll and fails to load it, even in the NeoLuaCmd test console, so I can’t see if that loads from there.

Perhaps writing a custom C# wrapper that returns a MongoClient object might help?


#9

Ok. So I wrote a quick wrapper like you suggested and it got a little further (Yey :smiley: ). I assume the new error is because of my incompetence so, I’d like for some help with it :slight_smile:

Wrapper:

using MongoDB.Driver;

namespace Mongo_Wrapper
{
    public class Test
    {
        public static MongoClient GetClient(string connString)
        {
            return new MongoClient(connString);
        }
    }
}

Client:

local client = clr.Mongo_Wrapper.Test:GetClient("mongodb://localhost:27017")

Error

Edit: I’m building against .NET 4.5 framework which I assume FiveM uses?


#10

FiveM (at least the client library for scripts) uses .NET 4.5.2 Framework.


#11

That’s a typical error due to conflicting .NET Standard library dependencies with the classical .NET Framework. Perhaps finding the right assembly from NuGet for System.Runtime.InteropServices.RuntimeInformation and placing it in the folder with the server EXE would help.


#12

Haha, that did it!

Thank you very much for the help :smiley: