C# 动态加载库

C# 动态加载库,c#,asp.net-web-api,reflection,types,system.reflection,C#,Asp.net Web Api,Reflection,Types,System.reflection,我有以下项目结构: webapi 类库A 类库B 类库C 这些是项目之间的参考 webapi直接引用A和B B直接引用C C有一种方法,需要确保加载a以通过反射使用其中定义的类型 我的代码实际上如下所示 public class C { public void MethodCallingBType( string fullClassName ) { //e.g. "MyNamespace.MyType, MyNamespace" string[] pa

我有以下项目结构:

  • webapi
  • 类库
    A
  • 类库
    B
  • 类库
    C
  • 这些是项目之间的参考

    • webapi
      直接引用
      A
      B
    • B
      直接引用
      C
    C
    有一种方法,需要确保加载
    a
    以通过反射使用其中定义的类型

    我的代码实际上如下所示

    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;
                }
            }
        }
    }
    
    此代码实际上不作为路径使用。GetDirectoryName函数不返回有效路径。除此之外,我想创建一种更好的方法,确保在查找其类型之前将
    B
    模块加载到内存中


    有什么建议吗?

    简单的
    汇编.Load
    不起作用?你不必知道位置,只需要知道名字

    我在相同的情况下使用了
    Assembly.CodeBase
    ,效果很好:

    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"));
    
    致以最良好的祝愿,
    Peter

    简单的
    程序集。加载
    不起作用?你不必知道位置,只需要知道名字

    我在相同的情况下使用了
    Assembly.CodeBase
    ,效果很好:

    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"));
    
    致以最良好的祝愿,
    Peter

    修改Peter的答案,但逻辑更正确,因为他的答案在联合收割机上会失败,并且没有理由创建URL以获取本地文件路径

    using System.Reflection;
    using System.IO;
    
    var appDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
    var myAssembly = Assembly.LoadFrom(Path.Combine(appDir, "MyAssebmly.dll"));
    

    修改Peter的答案,但逻辑更为正确,因为他将在联合收割机上失败,并且没有理由创建URL以获取本地文件路径

    using System.Reflection;
    using System.IO;
    
    var appDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
    var myAssembly = Assembly.LoadFrom(Path.Combine(appDir, "MyAssebmly.dll"));
    

    检查程序集基目录和专用路径;)@TomTom:程序集都位于WebAPI项目检查基本目录和专用路径的bin文件夹中。您没有阅读AppDomain的属性吗?有超过getExecutionGassembly;)他们都在那里;)检查程序集基目录和专用路径;)@TomTom:程序集都位于WebAPI项目检查基本目录和专用路径的bin文件夹中。您没有阅读AppDomain的属性吗?有超过getExecutionGassembly;)他们都在那里;)太好了,谢谢你。不知道CodeBase属性成员的情况。非常感谢。不知道代码库属性成员。是和否。代码库和位置之间存在差异。请看:我知道区别,但是您需要获取http路径,然后转换到位置。没有理由这么做。代码库用于特定需求,但这不是其中之一。AFAIK位置可能完全错误(即GAC中的某个位置),您无法找到其他DLL。如果我理解正确,当我们有两个应用程序(在C:\dir1和C:\dir2文件夹中)使用相同的MyCommon程序集时,那么这两个应用程序将使用完全相同的实例。从dir1或dir2或从GAC(我们称之为gacdir4mycommon)获得的信息并不重要。但是如果我们在dir1和dir2中使用不同版本的MyCommon2程序集(当然gacdir4mycommon中没有实例),那么至少有一个assembly.LoadFrom将使用assembly.Location从MyCommon失败。(继续:)如果您确定assembly.GetExecutionGassembly().Location始终是“真实的”(在GAC中从来没有),那么您的注释是正确的。但我认为这不是真的,至少对于IIS托管的应用程序来说是这样。我想区别在于,我从不使用GAC。我的库总是在父文件夹下,所以我不必担心版本控制。我从DLL地狱时代学到了教训。是和否。代码库和位置之间有区别。请看:我知道区别,但是您需要获取http路径,然后转换到位置。没有理由这么做。代码库用于特定需求,但这不是其中之一。AFAIK位置可能完全错误(即GAC中的某个位置),您无法找到其他DLL。如果我理解正确,当我们有两个应用程序(在C:\dir1和C:\dir2文件夹中)使用相同的MyCommon程序集时,那么这两个应用程序将使用完全相同的实例。从dir1或dir2或从GAC(我们称之为gacdir4mycommon)获得的信息并不重要。但是如果我们在dir1和dir2中使用不同版本的MyCommon2程序集(当然gacdir4mycommon中没有实例),那么至少有一个assembly.LoadFrom将使用assembly.Location从MyCommon失败。(继续:)如果您确定assembly.GetExecutionGassembly().Location始终是“真实的”(在GAC中从来没有),那么您的注释是正确的。但我认为这不是真的,至少对于IIS托管的应用程序来说是这样。我想区别在于,我从不使用GAC。我的库总是在父文件夹下,所以我不必担心版本控制。我从惨痛的日子里吸取了教训。