Esempio n. 1
0
        // 1. Load()方法接收一个String或AssemblyName类型作为参数,这个参数实际上是需要加载的程序集的强名称(名称,版本,语言,公钥标记)。
        //    例如.NET 2.0中的FileIOPermission类,它的强名称是:
        //    System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
        //    对于弱命名的程序集,则只会有程序集名称,而不会有版本,语言和公钥标记,例如 TestClassLibrary。
        // 细节
        // 1.1 CLR内部普遍使用了Load()方法来加载程序集,在Load()方法的内部,CLR首先会应用这个程序集的版本绑定重定向策略,接着在GAC中查找目标程序集。
        //     如果GAC中没有找到,则会在应用程序目录和子目录中寻找(应用配置文件的codebase所指定的位置)。
        // 1.2 如果希望加载弱命名程序集,Load()方法就不会去GAC中查找。
        // 1.3 当Load()找到目标程序集时,就会加载它,并返回一个相应Assembly对象的引用。
        // 1.4 当没有找到程序集时,会抛出System.IO.FileNotFoundException异常。
        // 1.5 当存在特定CPU架构的程序集时,CLR会优先加载当前架构的程序集(例如x86版本优先于IL中立版本)
        // 1.6 如果希望强迫加载某个架构版本的程序集,需要在强名称中加以指定。ProcessorArchitecture可以为x86 IA64 AMD64或MSIL,当然还有None
        // 1.7 Load方法与Win32函数中的LoadLibrary方法等价
        // 2. LoadFrom()方法可以从指定文件中加载程序集,通过查找程序集的AssemblyRef元数据表,得知所有引用和需要的程序集,然后在内部调用Load()方法进行加载。
        // 细节
        // 2.1 LoadFrom()首先会打开程序集文件,通过GetAssemblyName方法得到程序集名称,然后关闭文件,最后将得到的AssemblyName对象传入Load()方法中
        // 2.2 随后,Load()方法会再次打开这个文件进行加载。所以,LoadFrom()加载一个程序集时,会多次打开文件,造成了效率低下的现象(与Load相比)。
        // 2.3 由于内部调用了Load(),所以LoadFrom()方法还是会应用版本绑定重定向策略,也会在GAC和各个指定位置中进行查找。
        // 2.4 LoadFrom()会直接返回Load()的结果——一个Assembly对象的引用。
        // 2.5 如果目标程序集已经加载过,LoadFrom()不会重新进行加载。
        // 2.6 LoadFrom支持从一个URL加载程序集(如"http://www.abc.com/test.dll"),这个程序集会被下载到用户缓存文件夹中。
        // 2.7 从URL加载程序集时,如果计算机未联网,LoadFrom会抛出一个异常。如果IE被设置为“脱机工作”,则不会抛出异常,转而从缓存中寻找已下载的文件。
        // 3. LoadFile()从一个指定文件中加载程序集,它和LoadFrom()的不同之处在于LoadFile()不会加载目标程序集所引用和依赖的其他程序集。您需要自己控制并显示
        //    加载所有依赖的程序集。
        // 细节
        // 3.1 LoadFile()不会解析任何依赖
        // 3.2  LoadFile()可以多次加载同一程序集
        // 3.3  显式加载依赖程序集的方法是,注册AppDomain的AssemblyResolve事件
        #endregion
        internal override Assembly LoadAssembly(AssemblyLoadPolicy assemblyLoadPolicy)
        {
            if (_assembly != null)
            {
                return(_assembly);
            }

            // if the addin has not started, start it first.
            if (!_hostingAddin.Started)
            {
                _hostingAddin.Start();
            }

            var loadMethod = assemblyLoadPolicy.GetAssemblyLoadMethod(_hostingAddin);

            switch (loadMethod)
            {
            case AssemblyLoadMethod.Load:
                var assemblyName = AssemblyName.GetAssemblyName(_assemblyFile.LoadPath);
                _assembly = Assembly.Load(assemblyName);
                break;

            case AssemblyLoadMethod.LoadFrom:
                _assembly = Assembly.LoadFrom(_assemblyFile.LoadPath);
                break;

            case AssemblyLoadMethod.LoadFile:
                _assembly = Assembly.LoadFile(_assemblyFile.LoadPath);
                break;

            case AssemblyLoadMethod.LoadBytes:
                // 使用 Assembly.Load(byte[]) 重载,可以在加载程序集的同时,避免程序集被锁定,因此我们可以在运行时方便地替换和删除该程序集,
                // 而不会影响应用程序运行。另外,这种替换是原地替换,也意味着我们如果要升级或更新程序集,不必将程序集拷贝到一个阴影文件夹。
                var asmBytes = File.ReadAllBytes(_assemblyFile.LoadPath);
                _assembly = Assembly.Load(asmBytes);
                break;

            default:
                _assembly = Assembly.LoadFrom(_assemblyFile.LoadPath);
                break;
            }

            return(_assembly);
        }
Esempio n. 2
0
        internal AddinFramework(AddinOptions options)
        {
            _repository = new AddinRepository();

            _messageDialog      = options.MessageDialog ?? new DefaultMessageDialog();
            _nameConvention     = options.NameConvention ?? new DefaultNameConvention();
            _fileSettings       = options.FileSettings ?? new AddinFileSettings();
            _assemblyLoadPolicy = options.AssemblyLoadPolicy ?? new DefaultAssemblyLoadPolicy();
            _ebFactory          = options.ExtensionBuilderFactory ?? new ReflectionExtensionBuilderFactory();
            _epFactory          = options.ExtensionPointFactory ?? new ReflectionExtensionPointFactory();
            _eventBroker        = options.EventBroker ?? new EventBroker(new EventBrokerOption());
            _serviceProvider    = options.ServiceProvider ?? new DefaultServiceProvider();
            _stringLocalizer    = options.StringLocalizer ?? new DefaultStringLocalizer();

            LogManager.Initialize(new FileLogSetting(_fileSettings.DataDirectory, AddinFileSettings.LogFileName));
            _logger = LogManager.GetDefaultLogger();

            _properties = new Dictionary <HashKey, object>();
        }
            internal Assembly LoadAssembly(AssemblyLoadPolicy assemblyLoadPolicy)
            {
                if (_assembly != null)
                {
                    return(_assembly);
                }

                var selectedRuntimeAssembly = _runtimeAssemblies[0]; // use an assembly selecting policy ???

                _assembly = selectedRuntimeAssembly.Assembly ?? selectedRuntimeAssembly.LoadAssembly(assemblyLoadPolicy);

                //if (_runtimeAssemblies.Count > 1)
                //{
                //    // mark the other assemblies as Loaded, because they are all the same assembly.
                //    for (int i = 1; i < _runtimeAssemblies.Count; i++)
                //        _runtimeAssemblies[i].SetLoadStatus(true);
                //}

                return(_assembly);
            }
Esempio n. 4
0
 internal abstract Assembly LoadAssembly(AssemblyLoadPolicy assemblyLoadPolicy);
Esempio n. 5
0
 internal override Assembly LoadAssembly(AssemblyLoadPolicy assemblyLoadPolicy)
 {
     return(_assembly);
 }
Esempio n. 6
0
 public AddinOptions WithAssemblyLoadPolicy(AssemblyLoadPolicy assemblyLoadPolicy)
 {
     _assemblyLoadPolicy = assemblyLoadPolicy;
     return(this);
 }
        // @return value: whether the persistence file has been updated.
        public ResolutionResult Resolve(INameConvention nameConvention, AddinFileSettings fileSettings, AssemblyLoadPolicy assemblyLoadPolicy,
                                        AddinStorage addinStorage, AddinRelationManager relationManager,
                                        ScanFilePackResult scanFilePackResult)
        {
            var ctx = new ResolutionContext();
            var cm  = new ConvertionManager();

            InitializeDataTransformers(ctx, cm);

            if (assemblyLoadPolicy.PrivateAssemblyProbingDirectories != null)
            {
                foreach (var privateAssemblyProbingDirectory in assemblyLoadPolicy.PrivateAssemblyProbingDirectories)
                {
                    AssemblyResolution.AddSearchDirectory(privateAssemblyProbingDirectory);
                }
            }

            var resolver = new DefaultAddinResolver(addinStorage, relationManager, cm);

            // 强制 ExtensionBuilder 节点应用 NameConvention
            return(resolver.Resolve(nameConvention, ctx, scanFilePackResult));
        }