Exemplo n.º 1
0
        /// <summary>
        /// 从LIB目录加载程序集并返回新的程序集名称
        /// </summary>
        /// <param name="assemblyName">程序集名称</param>
        /// <returns>程序集定义</returns>
        private AssemblyDefinition LoadAssemblyFromLibDir(string assemblyName)
        {
            //如果是.NET运行库自带的程序集
            if (BundleUtils.IsAssemblyBelongsFcl(assemblyName))
            {
                return(null);
            }

            string libsDirPath = GetBundleLibsDirectoryName();

            if (!Directory.Exists(libsDirPath))
            {
                Directory.CreateDirectory(libsDirPath);
            }

            //string assemblyFileName = Path.Combine(libsDirPath, assemblyName + ".dll");
            string[] files = Directory.GetFiles(libsDirPath, assemblyName + ".dll", SearchOption.AllDirectories);

            if (files.Length == 0)
            {
                return(null);
            }

            var assemblyFileName = files[0];

            var readerParameter = new ReaderParameters()
            {
                AssemblyResolver = new CustomAssemblyResolver(
                    resolverAssemblyFullName =>
                {
                    var resolverAssemblyName = new AssemblyName(resolverAssemblyFullName);
                    var resolverDefinition   = this.GetBundleRefDefinition(resolverAssemblyFullName);
                    if (resolverDefinition == null)
                    {
                        return(LoadAssemblyFromLibDir(resolverAssemblyName.Name));
                    }
                    return(resolverDefinition);
                })
            };

            AssemblyDefinition     assemblyDefinition     = AssemblyDefinition.ReadAssembly(assemblyFileName, readerParameter);
            AssemblyNameDefinition assemblyNameDefinition = assemblyDefinition.Name;

            //去掉强签名
            BundleUtils.RemoveAssemblyStrongName(assemblyNameDefinition);

            //目前机制采用修订版本号方式控制程序集隔离
            MarkAssembleyVersion(assemblyNameDefinition);

            foreach (ModuleDefinition moduleDefinition in assemblyDefinition.Modules)
            {
                foreach (AssemblyNameReference refAssemblyNameReference in moduleDefinition.AssemblyReferences)
                {
                    string refAssemblyName = refAssemblyNameReference.Name;
                    //1.共享库优先
                    if (BundleAssemblyProvider.CheckHasShareLib(refAssemblyNameReference.FullName))
                    {
                        var shareAssembly = BundleAssemblyProvider.GetShareAssembly(refAssemblyNameReference.FullName);
                        refAssemblyNameReference.Name    = shareAssembly.GetName().Name;
                        refAssemblyNameReference.Version = shareAssembly.GetName().Version;
                        //目前共项目为反射,不移除强命名

                        log.Debug(string.Format("模块关联共享库程序集[{0}]!", assemblyName));

                        continue;
                    }

                    //2.尝试从当前Bundle已加载的程序集关联
                    var bundleRefAssembly = GetBundleRefAssembly(refAssemblyNameReference.FullName);
                    if (bundleRefAssembly != null)
                    {
                        refAssemblyNameReference.Name    = bundleRefAssembly.GetName().Name;
                        refAssemblyNameReference.Version = bundleRefAssembly.GetName().Version;
                        BundleUtils.RemoveAssemblyStrongName(refAssemblyNameReference);

                        log.Debug(string.Format("模块关联自身库程序集[{0}]!", assemblyName));

                        continue;
                    }

                    //3.Bundle Lib文件夹
                    var newRefAssemblyDefinition = LoadAssemblyFromLibDir(refAssemblyName);
                    if (newRefAssemblyDefinition != null)
                    {
                        refAssemblyNameReference.Name    = newRefAssemblyDefinition.Name.Name;
                        refAssemblyNameReference.Version = newRefAssemblyDefinition.Name.Version;
                        BundleUtils.RemoveAssemblyStrongName(refAssemblyNameReference);

                        log.Debug(string.Format("模块关联自身库程序集[{0}]!", assemblyName));

                        continue;
                    }

                    //目前对于依赖程序集的引用程序集如无发现,不做处理
                }
                moduleDefinition.Attributes &= ~ModuleAttributes.StrongNameSigned;
            }
            MemoryStream ms = new MemoryStream();

            assemblyDefinition.Write(ms);

            Assembly assembly;

            if (BundleConfigProvider.OSGi_NET_IS_DEBUG_MODE)
            {
                assembly = Assembly.LoadFrom(assemblyFileName);
            }
            else
            {
                assembly = Assembly.Load(ms.ToArray());
            }
            //将Lib程序集加载到程序集提供程序

            if (BundleConfigProvider.OSGi_NET_ALLTYPES_LOAD)
            {
                assembly.GetTypes();
            }

            log.Debug(string.Format("模块加载依赖程序集[{0}]!", assemblyName));

            AddRefAssembly(assemblyNameDefinition.FullName, assembly, assemblyDefinition);

            return(assemblyDefinition);
        }
Exemplo n.º 2
0
        /// <summary>
        /// 2.加载所需的所有程序集
        /// </summary>
        private void LoadAssemblys()
        {
            log.Debug("模块加载自身程序集!");

            AssemblyDefinition     bundleAssemblyDefinition     = AssemblyDefinition.ReadAssembly(bundleAssemblyFileName);
            AssemblyNameDefinition bundleAssemblyNameDefinition = bundleAssemblyDefinition.Name;

            //去掉强签名
            BundleUtils.RemoveAssemblyStrongName(bundleAssemblyNameDefinition);

            foreach (ModuleDefinition moduleDefinition in bundleAssemblyDefinition.Modules)
            {
                foreach (AssemblyNameReference assemblyNameReference in moduleDefinition.AssemblyReferences)
                {
                    string assemblyName = assemblyNameReference.Name;

                    //是否属于FCL
                    if (BundleUtils.IsAssemblyBelongsFcl(assemblyName))
                    {
                        continue;
                    }

                    //依赖项是否是Bundle
                    Bundle bundle = GetBundleFromRequiredBundles(assemblyName);
                    if (bundle != null)
                    {
                        AssemblyName requiredBundleAssemblyName = bundle.bundleAssembly.GetName();

                        assemblyNameReference.Name    = requiredBundleAssemblyName.Name;
                        assemblyNameReference.Version = requiredBundleAssemblyName.Version;
                        BundleUtils.RemoveAssemblyStrongName(assemblyNameReference);

                        log.Debug(string.Format("模块关联引用模块[{0}]!", assemblyName));

                        continue;
                    }

                    //1.首先尝试从共享程序集加载
                    if (BundleAssemblyProvider.CheckHasShareLib(assemblyNameReference.FullName))
                    {
                        //关联共享程序集
                        var shareAssembly = BundleAssemblyProvider.GetShareAssembly(assemblyNameReference.FullName);

                        assemblyNameReference.Name    = shareAssembly.GetName().Name;
                        assemblyNameReference.Version = shareAssembly.GetName().Version;
                        //目前共项目为反射,不移除强命名

                        log.Debug(string.Format("模块关联共享库程序集[{0}]!", assemblyName));

                        continue;
                    }

                    //2.尝试从当前Bundle已加载的程序集关联
                    var bundleRefAssembly = GetBundleRefAssembly(assemblyNameReference.FullName);
                    if (bundleRefAssembly != null)
                    {
                        assemblyNameReference.Name    = bundleRefAssembly.GetName().Name;
                        assemblyNameReference.Version = bundleRefAssembly.GetName().Version;
                        BundleUtils.RemoveAssemblyStrongName(assemblyNameReference);

                        log.Debug(string.Format("模块关联自身库程序集[{0}]!", assemblyName));

                        continue;
                    }

                    //3.尝试从lib目录重新加载
                    var newAssemblyDefinition = LoadAssemblyFromLibDir(assemblyName);
                    if (newAssemblyDefinition != null)
                    {
                        assemblyNameReference.Name    = newAssemblyDefinition.Name.Name;
                        assemblyNameReference.Version = newAssemblyDefinition.Name.Version;
                        BundleUtils.RemoveAssemblyStrongName(assemblyNameReference);

                        log.Debug(string.Format("模块关联自身库程序集[{0}]!", assemblyName));

                        continue;
                    }

                    //如果按如上步骤仍未发现程序集,抛出异常
                    throw new IOException(string.Format("{0}不能解析依赖的程序集[{1}]", this.ToString(), assemblyName));
                }
                moduleDefinition.Attributes &= ~ModuleAttributes.StrongNameSigned;
            }
            MemoryStream ms = new MemoryStream();

            bundleAssemblyDefinition.Write(ms);

            //是否Debug模式,如果debug,需要反射方式才能保证程序能进入Bundle断点
            if (BundleConfigProvider.OSGi_NET_IS_DEBUG_MODE)
            {
                bundleAssembly = Assembly.LoadFrom(bundleAssemblyFileName);
            }
            else
            {
                bundleAssembly = Assembly.Load(ms.ToArray());
            }
            //加载程序集中所有的类
            bundleAssembly.GetTypes();
            //将bundle程序集加入程序集提供程序
            AddRefAssembly(bundleAssemblyNameDefinition.FullName, bundleAssembly, bundleAssemblyDefinition);
        }