最近做一個插件項目,由於是mvc,mvc的cshtml文件最終會被視圖引擎編譯成.cs文件保存在c盤臨時目錄下,如果插件程序集沒有在bin目錄下,就會導致這些.cs文件找不到引用的程序集(比如用了強類型視圖,都會提示找不到程序集),經過兩天的琢磨,終於找到方法,發出來給大家共享:
原因:我項目的插件dll放在AppData/Bin目錄下,CLR在動態編譯.cshtml文件時,只會在bin目錄下找程序集,如果dll放其他目錄,需要指定。
方法1:在web.config中指定
<runtime>
<assemblyBinding xmlns = "urn:schemas-microsoft-com:asm.v1">
<probing privatePath = "AppData/Bin;" />
方法2:微軟已經加了棄用特性,但是實際上還是有作用的,目前不知道微軟棄用的原因
AppDomain.CurrentDomain.AppendPrivatePath(pluginDllPath);
方法3:
AppDomain.CurrentDomain.SetupInformation.PrivateBinPath=pluginDllPath;
或
AppDomain.CurrentDomain.SetData("PRIVATE_BINPAT", "AppData/Bin");
///經過測試無效,只修改屬性是沒有用的,內部有私有方法執行后才生效,所以這個方法最終衍化通過方法4來實現。
方法4,反編譯發現AppDomainSetup中有UpdateContextProperty和GetFusionContext方法,不過都是私有的,直接通過反射修改即可。
var m = typeof(AppDomainSetup).GetMethod("UpdateContextProperty", BindingFlags.NonPublic | BindingFlags.Static);
var funsion = typeof(AppDomain).GetMethod("GetFusionContext", BindingFlags.NonPublic | BindingFlags.Instance);
m.Invoke(null, new object[] { funsion.Invoke(AppDomain.CurrentDomain, null), "PRIVATE_BINPATH", "AppData/Bin" });