Home > database >  How to dynamically load a managed dll and invoke a method that returns custom class?
How to dynamically load a managed dll and invoke a method that returns custom class?

Time:10-29

I have the following situation..

My managed library needs to use an external (managed) library which is not 100% guaranteed to exist on the production platform. Therefore I need to use late binding (manually check if target dll exist and if yes load to memory). Of course if it doesn't exist, fail gracefully...

Once the target dll is in memory, I need to invoke a method that returns a custom class (its type is defined in the traget dll).

example:

External dll: Name = "ExtFactoryCreator.dll"

namespace Ext.Factory.Creator
{
    public static class ExtFactoryCreator
    {
       public static Factory FactoryCreator()
       {
           return new Factory();
       }
    }
    
    public class Factory
    {
        public Factory(){}
    }
}

My Library

public class ExtFactoryCreator.Mine
{
    private Ext.Factory.Creator.Factory localFactory;
    public void Init()
    {
        localFactory = AppDomain.CurrentDomain.Load("ExtFactoryCreator.dll").CreateInstance("ExtFactoryCreator").FactorCreator();
    }
}

(let me know if I got the syntax current).

But my problem, is how to define the return type from the external dll? I don't have a static reference to it in my project, therefore I can't define private Ext.Factory.Creator.Factory type?

CodePudding user response:

If you have control over the target library - just make it use some interface which you can share between that library and your main application.

If you don't have control over that library (third party), then it actually might be a good case for dynamic. For example we have this in library:

public static class ExtFactoryCreator
{
    public static Factory FactoryCreator()
    {
        return new Factory();
    }
}

public class Factory
{
    public Factory(){}

    public string Value => "test";

    public void Hello() {
        Console.WriteLine("Hello from library");
    }
}

Then we can use dynamic in main application:

public class LibraryWrapper {
    private dynamic _localFactory;
    public void Init() {
        // load assembly from somewhere if present
        var asm = Assembly.LoadFile(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "FullNetLib.dll"));
        // create that factory
        _localFactory = asm.GetType("FullNetLib.ExtFactoryCreator").GetMethod("FactoryCreator").Invoke(null, new object[0]);
    }

    public string GetValue() {
        // do not expose dynamic to the public if possible
        return _localFactory.Value;
    }

    public void Hello() {
        _localFactory.Hello();
    }
}
  •  Tags:  
  • c#
  • Related