接上一节
- /// <summary>
- /// Perform file deply
- /// </summary>
- /// <param name="plug">Plugin file info</param>
- /// <returns>Assembly</returns>
- private static Assembly PerformFileDeploy(FileInfo plug)
- {
- if (plug.Directory.Parent == null)
- throw new InvalidOperationException("The plugin directory for the" + plug.Name +
- "file exists in a folder outside of the allowed nopCommerce folder heirarchy");
- FileInfo shadowCopiedPlug;
- if (CommonHelper.GetTrustLevel() != AspNetHostingPermissionLevel.Unrestricted)
- {
- //all plugins will need to be copied to ~/Plugins/bin/
- //this is aboslutely required because all of this relies on probingPaths being set statically in the web.config
- //were running in med trust, so copy to custom bin folder
- var shadowCopyPlugFolder = Directory.CreateDirectory(_shadowCopyFolder.FullName);
- shadowCopiedPlug = InitializeMediumTrust(plug, shadowCopyPlugFolder);
- }
- else
- {
- var directory = AppDomain.CurrentDomain.DynamicDirectory;
- Debug.WriteLine(plug.FullName + "to" + directory);
- //were running in full trust so copy to standard dynamic folder
- shadowCopiedPlug = InitializeFullTrust(plug, new DirectoryInfo(directory));
- }
- //we can now register the plugin definition
- var shadowCopiedAssembly = Assembly.Load(AssemblyName.GetAssemblyName(shadowCopiedPlug.FullName));
- //add the reference to the build manager
- Debug.WriteLine("Adding to BuildManager:'{0}'", shadowCopiedAssembly.FullName);
- BuildManager.AddReferencedAssembly(shadowCopiedAssembly);
- return shadowCopiedAssembly;
- }
查看 CommonHelper.GetTrustLevel 方法:
- /// <summary>
- /// Finds the trust level of the running application (http://blogs.msdn.com/dmitryr/archive/2007/01/23/finding-out-the-current-trust-level-in-asp-net.aspx)
- /// </summary>
- /// <returns>The current trust level.</returns>
- public static AspNetHostingPermissionLevel GetTrustLevel()
- {
- if (!_trustLevel.HasValue)
- {
- //set minimum
- _trustLevel = AspNetHostingPermissionLevel.None;
- //determine maximum
- foreach (AspNetHostingPermissionLevel trustLevel in new[] {
- AspNetHostingPermissionLevel.Unrestricted,
- AspNetHostingPermissionLevel.High,
- AspNetHostingPermissionLevel.Medium,
- AspNetHostingPermissionLevel.Low,
- AspNetHostingPermissionLevel.Minimal
- })
- {
- try
- {
- new AspNetHostingPermission(trustLevel).Demand();
- _trustLevel = trustLevel;
- break; //we've set the highest permission we can
- }
- catch (System.Security.SecurityException)
- {
- continue;
- }
- }
- }
- return _trustLevel.Value;
- }
大体意思是: 如果新人级别没有值, 则先设置为不授予任何权限, 然后遍历权限, 从最大权限开始, 如果授予权限成功 就返回, 如果报错继续授予下一个权限, 就是授予当前能授予的最大权限.
如果不是最大权限的话, 创建 BIN 目录, 并调用方法:
- var shadowCopyPlugFolder = Directory.CreateDirectory(_shadowCopyFolder.FullName);
- shadowCopiedPlug = InitializeMediumTrust(plug, shadowCopyPlugFolder);
InitializeMediumTrust 方法如下:
- // <summary>
- /// Used to initialize plugins when running in Medium Trust
- /// </summary>
- /// <param name="plug"></param>
- /// <param name="shadowCopyPlugFolder"></param>
- /// <returns></returns>
- private static FileInfo InitializeMediumTrust(FileInfo plug, DirectoryInfo shadowCopyPlugFolder)
- {
- var shouldCopy = true;
- var shadowCopiedPlug = new FileInfo(Path.Combine(shadowCopyPlugFolder.FullName, plug.Name));
- //check if a shadow copied file already exists and if it does, check if it's updated, if not don't copy
- if (shadowCopiedPlug.Exists)
- {
- //it's better to use LastWriteTimeUTC, but not all file systems have this property
- //maybe it is better to compare file hash?
- var areFilesIdentical = shadowCopiedPlug.CreationTimeUtc.Ticks>= plug.CreationTimeUtc.Ticks;
- if (areFilesIdentical)
- {
- Debug.WriteLine("Not copying; files appear identical:'{0}'", shadowCopiedPlug.Name);
- shouldCopy = false;
- }
- else
- {
- //delete an existing file
- //More info: http://www.nopcommerce.com/boards/t/11511/access-error-nopplugindiscountrulesbillingcountrydll.aspx?p=4#60838
- Debug.WriteLine("New plugin found; Deleting the old file:'{0}'", shadowCopiedPlug.Name);
- File.Delete(shadowCopiedPlug.FullName);
- }
- }
- if (shouldCopy)
- {
- try
- {
- File.Copy(plug.FullName, shadowCopiedPlug.FullName, true);
- }
- catch (IOException)
- {
- Debug.WriteLine(shadowCopiedPlug.FullName + "is locked, attempting to rename");
- //this occurs when the files are locked,
- //for some reason devenv locks plugin files some times and for another crazy reason you are allowed to rename them
- //which releases the lock, so that it what we are doing here, once it's renamed, we can re-shadow copy
- try
- {
- var oldFile = shadowCopiedPlug.FullName + Guid.NewGuid().ToString("N") + ".old";
- File.Move(shadowCopiedPlug.FullName, oldFile);
- }
- catch (IOException exc)
- {
- throw new IOException(shadowCopiedPlug.FullName + "rename failed, cannot initialize plugin", exc);
- }
- //ok, we've made it this far, now retry the shadow copy
- File.Copy(plug.FullName, shadowCopiedPlug.FullName, true);
- }
- }
- return shadowCopiedPlug;
- }
根据传入值获得 bin 目录的 new fileinfo, 如果此文件已经存在, 则比较创建的 UTC 时间.
如果是旧文件就删除, 如果是新文件 就设置 需要拷贝为 false.
如果需要拷贝为 true, 则进行拷贝到 BIN... 最后返回 BIN 的全路径文件名.
最后根据这个文件名加载程序集, 并返回这个程序集.
用 foreach 循环加载剩余的 DLL.
最后设置 PluginType 类型的值 并添加到 referencedPlugins. 最后赋值
- ReferencedPlugins = referencedPlugins;
- IncompatiblePlugins = incompatiblePlugins;
PluginManager 类的 init 方法就是设置 ReferencedPlugins .
EnsurePluginsAreLoaded 方法内将它 (ReferencedPlugins .tolist) 赋值给_plugins.
GetPluginDescriptors 方法:
- /// <summary>
- /// Get plugin descriptors
- /// </summary>
- /// <param name="loadMode">Load plugins mode</param>
- /// <param name="storeId">Load records allowed only in a specified store; pass 0 to load all records</param>
- /// <param name="group">Filter by plugin group; pass null to load all records</param>
- /// <returns>Plugin descriptors</returns>
- public virtual IEnumerable<PluginDescriptor> GetPluginDescriptors(LoadPluginsMode loadMode = LoadPluginsMode.InstalledOnly,
- int storeId = 0, string group = null)
- {
- //ensure plugins are loaded
- EnsurePluginsAreLoaded();
- return _plugins.Where(p => CheckLoadMode(p, loadMode) && AuthenticateStore(p, storeId) && CheckGroup(p, group));
- }
最后一句, 帅选出 已安装的, 并且在 storeID 内的. group 为空也肯定为 true 的 plugins.
来源: http://www.bubuko.com/infodetail-3289801.html