zoukankan      html  css  js  c++  java
  • NOP源码分析十二

    接上一节

    /// <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.

  • 相关阅读:
    创业第一步:为员工打工
    C#笔记30:Trace、Debug和TraceSource的使用以及日志设计
    C#笔记29:程序集、应用程序配置及App.config和YourSoft.exe.config
    WPF快速指导1:资源
    并行编程之数据并行
    异常处理之ThreadException、unhandledException及多线程异常处理
    Efficient C#:为什么要把泛型作为返回值
    C#笔记31:本地化或多语言支持
    C#数据本地存储方案之SQLite
    C#笔记9:异常
  • 原文地址:https://www.cnblogs.com/runit/p/4213766.html
Copyright © 2011-2022 走看看