public ModuleController() { _app_domain_map = new Hashtable (); _ref_counts = new Hashtable (); _search_path = new ArrayList (); _roles = new ArrayList (); _resolver = new DepResolver (this, _search_path); _loader = new ModuleLoader (_search_path, _resolver); _info_map = new Hashtable (); }
public AppDomain LoadModule(ArrayList _parents, string _name, out ModuleInfo _info, bool checking, bool depcheck) { // Okay, this is tricky. First, we have to load the module into a temp domain // to retrieve its module info. Then, we have to attempt to resolve the dependencies. // This is going to be fun. Heh. if (_parents == null) _parents = new ArrayList (); // Try to find the module on the search path. string _filename = SearchForModule (_name); if (_filename == null) throw new ModuleNotFoundException (string.Format ("The module {0} was not found along the module search path.", _name)); // Okay, well, now we know the module exists at least in the file (we hope its a proper dll, but we'll see :). Now we // need to create the temporary AppDomain and load it to get the info from it. AppDomainSetup _setup = new AppDomainSetup (); _setup.ApplicationBase = Directory.GetCurrentDirectory (); AppDomain _tempDomain = AppDomain.CreateDomain (_name, new Evidence (), _setup); byte[] _raw_bytes = LoadRawFile (_filename); // set up the search path // Let's there this son of a bitch up. _tempDomain.ClearPrivatePath (); _tempDomain.AppendPrivatePath (Directory.GetCurrentDirectory ()); foreach (string s in _search_path) { _tempDomain.AppendPrivatePath (s); } // The throw here is mostly used from dep resolver calls, although it should also be caught by the immediate caller // (i.e. the application). try { _tempDomain.Load (_raw_bytes); } catch (BadImageFormatException e) { AppDomain.Unload (_tempDomain); throw new ModuleImageException (e.Message); } // Okay, now lets grab the module info from the assembly attributes. Assembly _asm = GetAssembly (_tempDomain, _name); try { _info = new ModuleInfo (_asm); } catch (ModuleInfoException e) { AppDomain.Unload (_tempDomain); throw new InvalidModuleException (e.Message); } // okay, now we've got the info, let's do some magic with the dependencies. // this will recursively load all of the appropriate assemblies as per the parsed // depedency tree. It will take into account dependency operators, such as AND, OR // OPT (optional). Very intelligent stuff. Of course, if there are no depends, // this just simply returns. This will of course continue updating the parents as needed // since each time a new module is loaded, the resolver is recursively called until // a module with no dependencies is found. This is cool. What this will do is call this method with // checking=true, which will cause it to just return if the module suceeds. This way // we can ensure we don't load unneeded module Z that is a dependency of X which depends // on Y, because if Z suceeds but Y fails, we don't want X, Y, or Z to fail. This way, // we can ensure the entire tree can be loaded first (this does take into account already // loaded assemblies). if (depcheck) { DepResolver _resolver = new DepResolver (_controller, _search_path); _parents.Add (_name); try { _resolver.Resolve (_parents, _info); } catch (Exception e) { AppDomain.Unload (_tempDomain); throw e; } } if (checking) { AppDomain.Unload (_tempDomain); return null; } // okay, they're good, lets load the suckers. // alright, we've got them all loaded, they exist in the assembly map. // now we create the *real* app domain. // We can't do any more with this. return _tempDomain; }
public ModuleLoader(ArrayList search_path, DepResolver resolver) { _search_path = search_path; _resolver = resolver; }