最近做一个插件项目,由于是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" });