Loading library dynamically

2019-09-09 20:00发布

I have the following project structure:

  1. Web API
  2. Class Library A
  3. Class Library B
  4. Class Library C

These are the references between the projects

  • Web API directly references A and B
  • B directly references C

C has a method which needs to ensure that A is loaded to use, by reflection, a type defined in it.

My code actually is like the following

public class C {
    public void MethodCallingBType( string fullClassName ) {
        //e.g. "MyNamespace.MyType, MyNamespace"
        string[] parts = fullClassName.Split( ',' );
        var className = parts[0].Trim();
        var assemblyName = parts[1].Trim();
        if ( !string.IsNullOrEmpty( assemblyName ) && !string.IsNullOrEmpty( className ) ) {
            string assemblyFolder = Path.GetDirectoryName( Assembly.GetExecutingAssembly().Location );
            string assemblyPath = Path.Combine( assemblyFolder, assemblyName + ".dll" );
            if ( File.Exists( assemblyPath ) ) {
                Assembly assembly = Assembly.LoadFrom( assemblyPath );
                Type type = assembly.GetType( className );
                result = Activator.CreateInstance( type ) as IInterfaceRunner;
            }
        }
    }
}

This code actually does not work as the Path.GetDirectoryName function does not return a valid path. Apart from this I would like to create a better way t ensure that B module is loaded in memory before looking for its type.

Any suggestion?

2条回答
女痞
2楼-- · 2019-09-09 20:21

The simple Assembly.Load does not work? You don't have to know the location, only the name.

I use Assembly.CodeBase in the same situation and it works fine:

string codebase = System.Reflection.Assembly.GetExecutingAssembly().CodeBase;
Uri p = new Uri(codebase);
string localPath = p.LocalPath;
var myassembly = System.Reflection.Assembly.LoadFrom(System.IO.Path.Combine(localPath, "MyAssebmly.dll"));

Best regards, Peter

查看更多
甜甜的少女心
3楼-- · 2019-09-09 20:29

Modifying Peter's answer, but the logic is more correct as his will fail on the combine and no reason to create a URL to get the local file path.

using System.Reflection;
using System.IO;

var appDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
var myAssembly = Assembly.LoadFrom(Path.Combine(appDir, "MyAssebmly.dll"));
查看更多
登录 后发表回答