首页 > 解决方案 > 如何动态加载托管 dll 并调用返回自定义类的方法?

问题描述

我有以下情况..

我的托管库需要使用不能 100% 保证在生产平台上存在的外部(托管)库。因此我需要使用后期绑定(手动检查目标 dll 是否存在以及是否加载到内存)。当然,如果它不存在,请优雅地失败......

一旦目标 dll 在内存中,我需要调用一个返回自定义类的方法(其类型在 traget dll 中定义)。

例子:

外部 dll:名称 =“ExtFactoryCreator.dll”

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

我的图书馆

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

(如果我的语法是最新的,请告诉我)。

但我的问题是如何定义外部 dll 的返回类型?我的项目中没有对它的静态引用,因此我无法定义private Ext.Factory.Creator.Factory类型?

标签: c#

解决方案


如果您可以控制目标库 - 只需让它使用一些您可以在该库和主应用程序之间共享的接口。

如果您无法控制该库(第三方),那么它实际上可能是dynamic. 例如,我们在库中有这个:

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");
    }
}

然后我们可以dynamic在主应用程序中使用:

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();
    }
}

推荐阅读