DarkRift.Server.PluginFactory.AddFile C# (CSharp) Method

AddFile() private method

Adds all plugin types in the file to the index.
private AddFile ( string file, DependencyResolutionStrategy dependencyResolutionStrategy, string searchedDirectory ) : void
file string The file containing the types.
dependencyResolutionStrategy DependencyResolutionStrategy The way to resolve dependencies for the plugin.
searchedDirectory string the directory that was searched to find this file.
return void
        internal void AddFile(string file, DependencyResolutionStrategy dependencyResolutionStrategy, string searchedDirectory)
        {
            //Check the file is a dll
            if (Path.GetExtension(file) != ".dll")
                throw new ArgumentException("The filepath supplied was not a DLL library.");

            //Check the file exists
            if (!File.Exists(file))
                throw new FileNotFoundException("The specified filepath does not exist.");

            //Log
            logger.Trace($"Searching '{file}' for plugins.");

            // Setup assembly resolver to help find dependencies recursively in the folder heirachy of the plugin
            AppDomain.CurrentDomain.AssemblyResolve += LoadFromSameFolder;

            Assembly LoadFromSameFolder(object sender, ResolveEventArgs args)
            {
                string rootFolderPath;
                if (dependencyResolutionStrategy == DependencyResolutionStrategy.RecursiveFromFile)
                {
                    rootFolderPath = Path.GetDirectoryName(file);
                }
                else if (searchedDirectory != null)
                {
                    rootFolderPath = searchedDirectory;
                }
                else
                {
                    return null;
                }

                string assemblyPath = SearchForFile(rootFolderPath, new AssemblyName(args.Name).Name + ".dll");
                if (assemblyPath == null)
                    return null;

                return Assembly.LoadFrom(assemblyPath);
            }

            //Load the assembly
            Assembly assembly;
            try
            {
                assembly = Assembly.LoadFrom(Path.GetFullPath(file));
            }
            catch (Exception e)
            {
                logger.Error($"{file} could not be loaded as an exception occurred.", e);
                return;
            }

            //Get the types in the assembly
            IEnumerable<Type> enclosedTypes;
            try
            {
                enclosedTypes = assembly.GetTypes();
            }
            catch (ReflectionTypeLoadException e)
            {
                logger.Error(
                    $"Failed to load one or more plugins from DLL file '{file}', see following logs for more info.\n\nIf this file is a DarkRift plugin rebuilding this plugin may help. Make sure it is built against the same .NET target as DarkRift is running and built to a compatible version ({Environment.Version}).\n\nThis exception can also occur when an unmanaged DLL is loaded by DarkRift because it is in a plugin search path. If this is the case, consider moving the unmanaged library out of any plugin search paths (https://docs.microsoft.com/en-us/dotnet/core/dependency-loading/default-probing#unmanaged-native-library-probing) or modify the plugin search path configuration to avoid discovering the library (e.g. reference individual DLL files instead of the containing directory).",
                    e
                );

                foreach (Exception loaderException in e.LoaderExceptions)
                {
                    logger.Error("Additional exception detail from LoaderExceptions property:", loaderException);
                }

                // The types unable to be loaded will be null here!
                enclosedTypes = e.Types.Where(t => t != null);
            }

            //Find the types that are plugins
            foreach (Type enclosedType in enclosedTypes)
            {
                if (enclosedType.IsSubclassOf(typeof(PluginBase)) && !enclosedType.IsAbstract)
                {
                    //Add the plugin
                    AddType(enclosedType);
                }
            }

            // Remove resolver again
            AppDomain.CurrentDomain.AssemblyResolve -= LoadFromSameFolder;
        }