• .Net冷知识之动态查找类型时的程序集路径问题


    最近的天气是相当的冷,冷的本来开这个博客时想写的大作(连标题都想好了)都懒得动手了。也罢,这第一篇博文还是写点轻松愉快的内容吧。

    page34_02(呃,基本上就这感觉吧)

    也罢,这个系列就写点基本没人用到的冷知识好了。说是系列,其实也就是想到哪写到哪,正式的说法就是“每集都是一个独立的故事”。

    今天就说说.Net中通过反射取得某个类型时,我们怎么知道这个类型在硬盘上的哪个角落?比如说,假如我们需要要求服务端动态载入某个数据源,那服务端怎么知道数据源在哪?

    网上大部分的教程都写着,可以使用Assembly.Load方法来先加载程序集,然后再用Assembly.GetType或者Assembly.GetTypes方法处理。

    这个方法很好很实用,基本上也就够了。不过如果这么无聊,也就算不上冷知识,更没有必要写这些了。

    如果有办法自动搜索程序集里面有没有暴露对应的类型,我们凭啥还要自行载入程序集?难道小又软的那群人也这么无聊?thV5XRWUR6其实还真是有办法解决这个问题的。

    image(呃,放错图了,请自行脑补多啦A梦掏道具时的声音)Type.GetType,就是你了。

    那么,这个方法有什么神奇的呢?Type.GetType有多个重载,其中除了一个没有参数的以外,剩下的几个重载要求至少一个字符串类型的typeName进行搜索,具体参见MSDN。比如下面这个例子:

    using System;
    
    namespace ConsoleApplication2
    {
        internal class Program
        {
            private static void Main(string[] args)
            {
                Type addedInRuntimeType = Type.GetType("LibA.TestClass, LibA, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null");
                foreach (var propertyInfo in addedInRuntimeType.GetProperties())
                {
                    Console.WriteLine(propertyInfo.Name);
                }
            }
        }
    }

    假设目录下我们有一个LibA.dll,LibA.dll里面包含了一个类LibA.TestClass,以上代码就能取得里面的全部属性名,接下来要对这个类型做什么羞羞的事情那就各位看官自行决定咯。

    但是,目前还是有一个限制没有解决。GetType方法的参数中和文件有关的就只有typeName了。可是这货并没有指定路径。如果要加载的类型所在的程序集在GAC中或者在当前程序集路径下那还好,如果因为各(xian)种(de)原(dan)因(teng)需要放到子目录该怎么办呢?比如说要在子目录“runtime”以及“runtme2”下进行搜索又该怎么办呢?还是直接放代码吧:

    using System;
    
    namespace ConsoleApplication2
    {
        internal class Program
        {
            private static void Main(string[] args)
            {
                AppDomain.CurrentDomain.AppendPrivatePath("runtime");
                AppDomain.CurrentDomain.AppendPrivatePath("runtime2");
                
                Type addedInRuntimeType = Type.GetType("LibA.TestClass, LibA, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null");
                foreach (var propertyInfo in addedInRuntimeType.GetProperties())
                {
                    Console.WriteLine(propertyInfo.Name);
                }
            }
        }
    }

    AppDomain.CurrentDomain.AppendPrivatePath可以增加CLR搜索的路径,不过这个方法已经被标记为obsolete了。请自行无视这个警告吧。或者按如下代码处理:

    #pragma  warning disable 618
                AppDomain.CurrentDomain.AppendPrivatePath("runtime");
    #pragma warning restore 618

    继续说点,其实这个路径也可以写在配置文件中的。MSDN说明在此,例子如下:

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
      <runtime>
        <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
          <probing privatePath="runtime;runtime2" />
        </assemblyBinding>
      </runtime>
    </configuration>

    到这里,这个无聊的问题我们就已经完全解决了。下回的内容……呃……完全木有想法th3AAKMNT9

  • 相关阅读:
    第一部分:并发理论基础03->互斥锁(上),解决原子性问题
    第一部分:并发理论基础02->java内存模型,看java如何解决可见性和有序性问题
    第一部分:并发理论基础01->可见性,原子性,有序性
    第五部分-并发编程模型4:CSP模型,golang的主力军
    第五部分-并发编程模型3:协程
    io模型
    容器基础4:重识docker容器
    第五部分-并发编程模型1:Actor模型
    AcWing 380. 舞动的夜晚
    AcWing 379.Vani和Cl2捉迷藏
  • 原文地址:https://www.cnblogs.com/Nyarlathotep/p/3550631.html
Copyright © 2020-2023  润新知