internal static Assembly LoadAssembly(string filePath, bool forceReload)
 {
     Assembly[] assemblyArray;
     if (!forceReload && !SharedUtil.IsEmpty((ICollection)(assemblyArray = AppDomain.CurrentDomain.GetAssemblies())))
     {
         foreach (Assembly assembly in assemblyArray)
         {
             if (((assembly != null) && !(assembly is AssemblyBuilder)) && (!SharedUtil.IsEmpty(assembly.CodeBase) && IOUtil.PathEquals(assembly.CodeBase, filePath)))
             {
                 return(assembly);
             }
         }
     }
     lock (LoadedAssemblies.SyncRoot)
     {
         if (forceReload || !LoadedAssemblies.ContainsKey(filePath = IOUtil.NormalizePath(filePath)))
         {
             byte[] buffer;
             using (FileStream stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))
             {
                 buffer = new byte[stream.Length];
                 using (MemoryStream stream2 = new MemoryStream(buffer, true))
                 {
                     IOUtil.CopyStream(stream, stream2);
                 }
             }
             LoadedAssemblies[filePath] = Assembly.Load(buffer);
         }
         return(LoadedAssemblies[filePath] as Assembly);
     }
 }
Esempio n. 2
0
        public static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) {

            AssemblyName assemblyName = new AssemblyName(args.Name);
            if (LoadedAssemblies.ContainsKey(assemblyName.Name)) {
                return LoadedAssemblies[assemblyName.Name];
            } else {
                return null;
            }
        }
Esempio n. 3
0
        public void ConfigureServices(IServiceCollection serviceCollection)
        {
            Dictionary <Assembly, List <Plugin> > assemblies = new Dictionary <Assembly, List <Plugin> >();

            foreach (var grouped in PluginConstructors.Where(x => typeof(IServiceHolder).IsAssignableFrom(x.Type)).GroupBy(x => x.Type.Assembly).ToArray())
            {
                List <Plugin> assemblyInstances = new List <Plugin>();
                foreach (var constructor in grouped)
                {
                    if (constructor.RequiresServices)
                    {
                        Log.Warn($"Could not configure plugin as ServiceHolder. IServiceHolder implementations require an empty Constructor! (Type: {constructor.Type})");
                        continue;
                    }

                    if (CreateInstance(constructor, out Plugin instance, assemblies))
                    {
                        PluginContainer.RegisterSingleton(instance.GetType(), instance);

                        IServiceHolder serviceHolder = instance as IServiceHolder;
                        serviceHolder?.ConfigureServices(serviceCollection);
                        // pluginInstances++;

                        assemblyInstances.Add(instance);
                        //serviceCollection.AddSingleton(constructor.Type, instance);
                    }

                    PluginConstructors.Remove(constructor);
                }

                if (!assemblies.ContainsKey(grouped.Key))
                {
                    assemblies.Add(grouped.Key, assemblyInstances);
                }
                else
                {
                    assemblies[grouped.Key].AddRange(assemblyInstances);
                }

                //PluginConstructors.Remove(constructor);
            }

            foreach (var grouped in assemblies)
            {
                if (LoadedAssemblies.ContainsKey(grouped.Key))
                {
                    LoadedAssemblies[grouped.Key].PluginTypes.AddRange(grouped.Value.Select(x => x.GetType()));
                    continue;
                }
                else
                {
                    LoadedAssemblies.Add(grouped.Key,
                                         new LoadedAssembly(grouped.Key, grouped.Value.Select(x => x.GetType()), new Assembly[0],
                                                            grouped.Key.Location));
                }
            }
        }
Esempio n. 4
0
        private void ResolveDenpendency(Assembly assembly)
        {
            if (LoadedAssemblies == null)
            {
                LoadedAssemblies = AppDomain.CurrentDomain.GetAssemblies().ToDictionary(m => GetAssemblyNameVersion(m.GetName()));
            }
            string nameVersion = GetAssemblyNameVersion(assembly.GetName());

            if (!LoadedAssemblies.ContainsKey(nameVersion))
            {
                LoadedAssemblies.Add(nameVersion, assembly);
            }
            List <Assembly>            dependencies = new List <Assembly>();
            DependencyAssemblyResolver dependencyAssemblyResolver = new DependencyAssemblyResolver(Path.GetDirectoryName(assembly.Location));

            foreach (var item in dependencyAssemblyResolver.ResolveAssemblyPaths())
            {
                AssemblyName assemblyName        = AssemblyName.GetAssemblyName(item);
                string       assemblyNameVersion = GetAssemblyNameVersion(assemblyName);
                if (!LoadedAssemblies.ContainsKey(assemblyNameVersion))
                {
                    Assembly assemblyDep = AssemblyLoadContext.Default.LoadFromAssemblyPath(item);
                    DependencyAssemblies.Add(assemblyDep);
                    LoadedAssemblies.Add(assemblyNameVersion, assemblyDep);
                    dependencies.Add(assemblyDep);
                }
            }

            PluginDescriptor plugin = null;

            foreach (var typeInfo in assembly.DefinedTypes)
            {
                if (typeInfo.IsAbstract || typeInfo.IsInterface)
                {
                    continue;
                }

                if (PluginTypeInfo.IsAssignableFrom(typeInfo))
                {
                    plugin = new PluginDescriptor
                    {
                        PluginType        = typeInfo.AsType(),
                        Assembly          = assembly,
                        Dependencies      = dependencies,
                        CurrentPluginPath = CurrentPath
                    };
                }
            }

            if (plugin != null)
            {
                PluginActivtor.LoadedPlugins.Add(plugin);
            }
        }
Esempio n. 5
0
        public AssetTypeValueField GetMonoBaseField(AssetContainer cont, string managedPath)
        {
            var file     = cont.FileInstance.file;
            var item     = cont.Item;
            var baseTemp = new AssetTypeTemplateField();

            baseTemp.FromClassDatabase(Am.classFile, AssetHelper.FindAssetClassByID(Am.classFile, item.TypeID), 0);
            var mainAti     = new AssetTypeInstance(baseTemp, cont.FileReader, item.Position);
            var scriptIndex = item.MonoID;

            if (scriptIndex != 0xFFFF)
            {
                var monoScriptCont = GetAssetContainer(mainAti.GetBaseField().Get("m_Script"));
                if (monoScriptCont == null)
                {
                    return(null);
                }

                var scriptBaseField = monoScriptCont.TypeInstance.GetBaseField();
                var scriptName      = scriptBaseField.Get("m_Name").GetValue().AsString();
                var scriptNamespace = scriptBaseField.Get("m_Namespace").GetValue().AsString();
                var assemblyName    = scriptBaseField.Get("m_AssemblyName").GetValue().AsString();
                var assemblyPath    = Path.Combine(managedPath, assemblyName);

                if (scriptNamespace != string.Empty)
                {
                    scriptName = scriptNamespace + "." + scriptName;
                }

                if (File.Exists(assemblyPath))
                {
                    if (!LoadedAssemblies.ContainsKey(assemblyName))
                    {
                        LoadedAssemblies.Add(assemblyName, MonoDeserializer.GetAssemblyWithDependencies(assemblyPath));
                    }
                    var asmDef = LoadedAssemblies[assemblyName];

                    var mc = new MonoDeserializer();
                    mc.Read(scriptName, asmDef, file.header.format);
                    var monoTemplateFields = mc.children;

                    var templateField = baseTemp.children.Concat(monoTemplateFields).ToArray();
                    baseTemp.children      = templateField;
                    baseTemp.childrenCount = baseTemp.children.Length;

                    mainAti = new AssetTypeInstance(baseTemp, cont.FileReader, item.Position);
                }
            }
            return(mainAti.GetBaseField());
        }
Esempio n. 6
0
        public AssetTypeValueField GetConcatMonoBaseField(AssetContainer cont, string managedPath)
        {
            AssetsFile file = cont.FileInstance.file;
            AssetTypeTemplateField baseTemp = new AssetTypeTemplateField();
            baseTemp.FromClassDatabase(am.classFile, AssetHelper.FindAssetClassByID(am.classFile, cont.ClassId), 0);
            AssetTypeInstance mainAti = new AssetTypeInstance(baseTemp, cont.FileReader, cont.FilePosition);
            ushort scriptIndex = cont.MonoId;
            if (scriptIndex != 0xFFFF)
            {
                AssetContainer monoScriptCont = GetAssetContainer(cont.FileInstance, mainAti.GetBaseField().Get("m_Script"), false);
                if (monoScriptCont == null)
                    return null;

                AssetTypeValueField scriptBaseField = monoScriptCont.TypeInstance.GetBaseField();
                string scriptName = scriptBaseField.Get("m_Name").GetValue().AsString();
                string scriptNamespace = scriptBaseField.Get("m_Namespace").GetValue().AsString();
                string assemblyName = scriptBaseField.Get("m_AssemblyName").GetValue().AsString();
                string assemblyPath = Path.Combine(managedPath, assemblyName);

                if (scriptNamespace != string.Empty)
                    scriptName = scriptNamespace + "." + scriptName;

                if (File.Exists(assemblyPath))
                {
                    AssemblyDefinition asmDef;

                    if (!LoadedAssemblies.ContainsKey(assemblyName))
                    {
                        LoadedAssemblies.Add(assemblyName, MonoDeserializer.GetAssemblyWithDependencies(assemblyPath));
                    }
                    asmDef = LoadedAssemblies[assemblyName];

                    MonoDeserializer mc = new MonoDeserializer();
                    mc.Read(scriptName, asmDef, file.header.format);
                    List<AssetTypeTemplateField> monoTemplateFields = mc.children;

                    AssetTypeTemplateField[] templateField = baseTemp.children.Concat(monoTemplateFields).ToArray();
                    baseTemp.children = templateField;
                    baseTemp.childrenCount = baseTemp.children.Length;

                    mainAti = new AssetTypeInstance(baseTemp, cont.FileReader, cont.FilePosition);
                }
            }
            return mainAti.GetBaseField();
        }
        /// <summary>
        /// Gets the <see cref="Assembly"/> Indexed corresponding to the Loaded
        /// <paramref name="path"/> according to the <paramref name="comparisonType"/>. Assume
        /// that <see cref="AddDependency(string)"/> was invoked prior to Indexing the Path.
        /// Returns the corresponding <see cref="Assembly"/> Reference from
        /// <see cref="AdditionalReferencePaths"/> when loaded context fails.
        /// </summary>
        /// <param name="path">We are interested in identifying the Resolved or Augmented Path.</param>
        /// <param name="comparisonType">Overriding the default <see cref="StringComparison"/> is allowed.</param>
        /// <returns></returns>
        public Assembly this[string path, StringComparison comparisonType]
        {
            get
            {
                // TODO: TBD: we could potentially instruct a search heuristic to search based on Equals, or possible also Containing...
                Assembly GetAdditionalReference()
                {
                    // TODO: TBD: should these be `augmenting´ the normally added dependencies?
                    // TODO: TBD: or should these be fed into the normally resolved dependency context?

                    // TODO: TBD: may capture a default comparison type applicable over the range of questions... i.e. OrdinalIgnoreCase
                    var chosen = AdditionalReferencePaths.SingleOrDefault(
                        x => !IsNullOrEmpty(x) &&
                        GetFileName(x).Equals(GetFileName(path), comparisonType)
                        );

                    return(!IsNullOrEmpty(chosen) && File.Exists(chosen) ? Assembly.LoadFile(GetFullPath(chosen)) : null);
                }

                return(LoadedAssemblies.ContainsKey(path) ? LoadedAssemblies[path] : GetAdditionalReference());
            }
        }
Esempio n. 8
0
        /// <summary>
        /// The constructor of the Assembly Resolver
        /// </summary>
        /// <param name="applicationConfig">ApplicationConfig</param>
        public AssemblyResolver(ApplicationConfig applicationConfig)
        {
            _applicationConfig = applicationConfig;
            // setup the regex
            var regexExtensions = string.Join("|", applicationConfig.Extensions.Select(e => e.Replace(".", @"\.")));

            _assemblyResourceNameRegex = new Regex($@"^(costura\.)*(?<assembly>.*)({regexExtensions})$", RegexOptions.Compiled | RegexOptions.IgnoreCase);
            _assemblyFilenameRegex     = new Regex($@".*\\(?<assembly>.*)({regexExtensions})$", RegexOptions.Compiled | RegexOptions.IgnoreCase);

            Resources = new ManifestResources(simpleAssemblyName => LoadedAssemblies.ContainsKey(simpleAssemblyName) ? LoadedAssemblies[simpleAssemblyName] : null);

            foreach (var loadedAssembly in AppDomain.CurrentDomain.GetAssemblies())
            {
                LoadedAssemblies[loadedAssembly.GetName().Name] = loadedAssembly;
            }

            // Register assembly loading
            AppDomain.CurrentDomain.AssemblyLoad += AssemblyLoad;
            // Register assembly resolving
            AppDomain.CurrentDomain.AssemblyResolve += AssemblyResolve;
            AppDomain.CurrentDomain.ProcessExit     += (sender, args) => RemoveCopiedAssemblies();

            ScanForAssemblies();
        }
Esempio n. 9
0
        //private Assembly AssemblyResolving(AssemblyLoadContext arg1, AssemblyName arg2)
        //{
        //    if (arg2.FullName == CurrentAssembly.FullName)
        //    {
        //        return CurrentAssembly;
        //    }
        //    var deps = DependencyContext.Default;
        //    if (deps.CompileLibraries.Any(d => d.Name == arg2.Name))
        //    {
        //        return Assembly.Load(arg2);
        //    }

        //    foreach (var item in DependencyAssemblies)
        //    {
        //        if (item.FullName == arg2.FullName)
        //        {
        //            return item;
        //        }
        //    }
        //    return null;
        //}
        private void ResolveDenpendency(Assembly assembly)
        {
            string currentName = assembly.GetName().Name;

            if (CompileLibraries == null)
            {
                CompileLibraries = new HashSet <string>();
                foreach (var item in DependencyContext.Default.CompileLibraries)
                {
                    if (!CompileLibraries.Contains(item.Name))
                    {
                        CompileLibraries.Add(item.Name);
                    }
                }
            }
            List <CompilationLibrary> dependencyCompilationLibrary = DependencyContext.Load(assembly)
                                                                     .CompileLibraries.Where(de => PluginInfos.All(m => m.Name != de.Name) && de.Name != currentName && !CompileLibraries.Contains(de.Name))
                                                                     .ToList();

            if (LoadedAssemblies == null)
            {
                LoadedAssemblies = AppDomain.CurrentDomain.GetAssemblies().ToDictionary(m => m.GetName().Name);
            }

            dependencyCompilationLibrary.Each(libaray =>
            {
                foreach (var item in libaray.ResolveReferencePaths(new DependencyAssemblyResolver(Path.GetDirectoryName(assembly.Location))))
                {
                    string assemblyName = AssemblyName.GetAssemblyName(item).Name;
                    if (!LoadedAssemblies.ContainsKey(assemblyName))
                    {
                        Assembly assemblyDep = AssemblyLoadContext.Default.LoadFromAssemblyPath(item);
                        DependencyAssemblies.Add(assemblyDep);
                        LoadedAssemblies.Add(assemblyName, assemblyDep);
                    }
                }
            });

            PluginDescriptor plugin = null;

            foreach (var typeInfo in assembly.DefinedTypes)
            {
                if (typeInfo.IsAbstract || typeInfo.IsInterface)
                {
                    continue;
                }

                if (PluginTypeInfo.IsAssignableFrom(typeInfo))
                {
                    plugin = new PluginDescriptor
                    {
                        PluginType        = typeInfo.AsType(),
                        Assembly          = assembly,
                        Dependency        = dependencyCompilationLibrary,
                        CurrentPluginPath = CurrentPath
                    };
                }
            }

            if (plugin != null)
            {
                PluginActivtor.LoadedPlugins.Add(plugin);
            }
        }
Esempio n. 10
0
        /// <summary>
        /// This is called when a new assembly is loaded, we need to know this
        /// </summary>
        /// <param name="sender">object</param>
        /// <param name="args">AssemblyLoadEventArgs</param>
        private void AssemblyLoad(object sender, AssemblyLoadEventArgs args)
        {
            var loadedAssembly = args.LoadedAssembly;
            var assemblyName   = loadedAssembly.GetName().Name;

            if (Log.IsVerboseEnabled())
            {
                Log.Verbose().WriteLine("Loaded {0}", assemblyName);
            }
            LoadedAssemblies[assemblyName] = loadedAssembly;

            if (!_applicationConfig.ScanForEmbeddedAssemblies)
            {
                return;
            }

            // Ignore resource checking on certain assemblies
            if (AssembliesToIgnore.IsMatch(assemblyName))
            {
                return;
            }

            string[] resources;
            try
            {
                resources = Resources.GetCachedManifestResourceNames(loadedAssembly);
            }
            catch (Exception ex)
            {
                Log.Warn().WriteLine(ex, "Couldn't retrieve resources from {0}", loadedAssembly.GetName().Name);
                return;
            }
            foreach (var resource in resources)
            {
                var resourceMatch = _assemblyResourceNameRegex.Match(resource);
                if (!resourceMatch.Success)
                {
                    continue;
                }

                var embeddedAssemblyName = resourceMatch.Groups["assembly"].Value;
                if (LoadedAssemblies.ContainsKey(embeddedAssemblyName))
                {
                    // Ignoring already loaded assembly, as we cannot unload.
                    continue;
                }
                var newAssemblyLocation = new AssemblyLocationInformation(embeddedAssemblyName, loadedAssembly, resource);
                if (AvailableAssemblies.TryGetValue(embeddedAssemblyName, out var availableAssemblyLocationInformation))
                {
                    if (availableAssemblyLocationInformation.FileDate > newAssemblyLocation.FileDate)
                    {
                        continue;
                    }
                }
                if (Log.IsVerboseEnabled())
                {
                    Log.Verbose().WriteLine("Detected additional assembly {0} in {1}", embeddedAssemblyName, loadedAssembly.GetName().Name);
                }
                AvailableAssemblies[embeddedAssemblyName] = newAssemblyLocation;
            }
        }
Esempio n. 11
0
        public void LoadPlugins()
        {
            int pluginInstances = 0;

            Dictionary <Assembly, List <Plugin> > assemblies = new Dictionary <Assembly, List <Plugin> >();

            //Load all plugins that do NOT have a reference to any other plugins.
            foreach (var grouped in PluginConstructors.Where(x => !x.ReferencesOtherPlugin).GroupBy(x => x.Type.Assembly).ToArray())
            {
                List <Plugin> assemblyInstances = new List <Plugin>();
                foreach (var constructor in grouped)
                {
                    if (CreateInstance(constructor, out Plugin instance, assemblies))
                    {
                        PluginContainer.RegisterSingleton(instance.GetType(), instance);
                        pluginInstances++;

                        assemblyInstances.Add(instance);
                    }

                    PluginConstructors.Remove(constructor);
                }

                if (!assemblies.ContainsKey(grouped.Key))
                {
                    assemblies.Add(grouped.Key, assemblyInstances);
                }
                else
                {
                    assemblies[grouped.Key].AddRange(assemblyInstances);
                }
            }

            LinkedList <PluginConstructorData> ordered = new LinkedList <PluginConstructorData>();

            var requiresOthers = PluginConstructors.Where(x => x.ReferencesOtherPlugin).ToArray();

            foreach (var grouped in requiresOthers)
            {
                var thisNode = ordered.Find(grouped);
                if (thisNode == null)
                {
                    thisNode = ordered.AddLast(grouped);
                }

                var otherPlugins = grouped.Dependencies.Where(x => x.IsPluginInstance).Select(x => x.Type).ToArray();
                foreach (var otherDependency in otherPlugins)
                {
                    var found = requiresOthers.FirstOrDefault(x => x.Type == otherDependency);
                    if (found != null)
                    {
                        ordered.AddBefore(thisNode, found);
                    }
                }
            }

            bool done = false;

            var current = ordered.First;

            do
            {
                var currentValue = current?.Value;
                var next         = current?.Next;
                if (next == null || currentValue == null)
                {
                    done = true;
                    break;
                }

                if (currentValue.Requires(next.Value))
                {
                    current.Value = next.Value;
                    next.Value    = currentValue;
                }

                current = next;
            } while (!done);

            foreach (var item in ordered)
            {
                // List<OpenPlugin> assemblyInstances = new List<OpenPlugin>();

                if (PluginContainer.TryResolve(item.Type, out _))
                {
                    continue;
                }

                if (CreateInstance(item, out var instance, assemblies))
                {
                    PluginContainer.RegisterSingleton(item.Type, instance);            //.Add(instance);
                    pluginInstances++;


                    if (!assemblies.ContainsKey(item.Type.Assembly))
                    {
                        assemblies.Add(item.Type.Assembly, new List <Plugin>()
                        {
                            instance
                        });
                    }
                    else
                    {
                        assemblies[item.Type.Assembly].Add(instance);
                    }
                }
            }


            Log.Info($"Registered {pluginInstances} plugin instances");

            foreach (var grouped in assemblies)
            {
                if (LoadedAssemblies.ContainsKey(grouped.Key))
                {
                    LoadedAssemblies[grouped.Key].PluginTypes.AddRange(grouped.Value.Select(x => x.GetType()));
                    continue;
                }
                else
                {
                    LoadedAssemblies.Add(grouped.Key,
                                         new LoadedAssembly(grouped.Key, grouped.Value.Select(x => x.GetType()), new Assembly[0],
                                                            grouped.Key.Location));
                }
            }
        }