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;
 }