Ejemplo n.º 1
0
        public virtual List <Tuple <Assembly, Type> > Start()
        {
            if (DependencyResolver.IsSet)
            {
                return(ModuleUtilities.GetLoadedModuleAssemblies(AppDomain.CurrentDomain.GetAssemblies()));
            }

            string         binPath         = GetBinPath();
            IList <string> binDllFileNames = GetBinDllFileNames(binPath);
            List <ComposablePartCatalog> binComposablePartCatalogs = GetBinComposablePartCatalogs(binDllFileNames,
                                                                                                  binPath);

            CreateModuleDirectories();

            //TODO: Auto Register (Convention parts mef...) Action Handlers
            //TODO: Auto Register Controllers insinde module content (metadata) avec un action handler sur la création d'un module?


            // Set Assembly Resolver (TODO : A quoi ca sert??? encore utile?? - je l'Enleve jusqu'a preuve du contraire...)
            //Apparament ca sert dans la génération des vues Razor.. si je l'enlève les vues ne sont pas générées!!
            //http://stackoverflow.com/questions/12128890/best-practices-for-composed-asp-net-mvc-web-applications-mef-areas-di
            //TODO: Si ca sert juste pour Razor il faudrait pas chercher dans tous les assemblies!? (performance)
            AppDomain.CurrentDomain.AssemblyResolve += new AssemblyResolver().CurrentDomainAssemblyResolve;

            // Pre Modules and Parts Composition
            //var composableParts = new List<ComposablePartCatalog> { new DirectoryCatalog(GetBinPath()) };

            List <Assembly> allLoadedAssemblies = AppDomain.CurrentDomain.GetAssemblies()
                                                  .Where(
                a =>
                !a.IsDynamic &&
                binDllFileNames.Contains(Path.GetFileName(a.Location)))
                                                  .ToList();
            List <Tuple <Assembly, Type> > loadedModuleAssemblies =
                ModuleUtilities.GetLoadedModuleAssemblies(allLoadedAssemblies);

            //On crée un DependencyResolver temporaire pour aller chercher les IPartRegistryRetriever
            List <Assembly> moduleDirectoryAssemblies = CopyDllToExecutionPath(true, ref loadedModuleAssemblies,
                                                                               ref allLoadedAssemblies);

            foreach (var loadedModuleAssembly in loadedModuleAssemblies)
            {
                CreateModuleInitializerInstance(loadedModuleAssembly.Item2).PreInitialize();
            }

            List <ComposablePartCatalog> allComposableParts =
                binComposablePartCatalogs.Union(
                    moduleDirectoryAssemblies.Select(
                        moduleDirectoryAssembly => new AssemblyCatalog(moduleDirectoryAssembly))).ToList();
            IDependencyResolver dependencyResolver = GetDependencyResolver(allComposableParts);

            DependencyResolver.SetResolver(dependencyResolver);

            //Ajouter les conventions
            List <IPartRegistryRetriever> composablePartCatalogRetrievers =
                DependencyResolver.Current.GetServices <IPartRegistryRetriever>().ToList();

            //PAs besoin de faire le join avec les modules assemblies car ils sont ajoutés a la collection allLoadedAssemblies
            //TODO: Rouler les conventions juste sur les module assemblies
            foreach (Assembly assembly in allLoadedAssemblies
                     /*.Union(moduleDirectoryAssemblies).DistinctBy(a => a.FullName)*/)
            {
                //Attention si jamais on fait des conventions aussi dans LoadBinPartsAndSetTemporaryDependencyResolverForInitializationPeriod elles vont etre faites 2 fois...
                AddConventionParts(assembly, allComposableParts, composablePartCatalogRetrievers);
            }

            //Faire le DependencyResolver final (après conventions)
            dependencyResolver = GetDependencyResolver(allComposableParts);
            DependencyResolver.SetResolver(dependencyResolver);

            //On les fais tous d'u coup avec RavenDB - plus performant et limites de queries par défault
            InstallOrUpdateModules(loadedModuleAssemblies, dependencyResolver);
            InitializeModules(loadedModuleAssemblies, dependencyResolver);

            return(loadedModuleAssemblies);
        }
Ejemplo n.º 2
0
        //TODO: Faire des tests et refactorer
        //TODO: Gérer les Framework Dependecies (dépendances a des dll du framework .net - on veut pas les ajouter au répertoire du module... il faudrait faire un autre fichier text pe et les charger...)
        protected virtual List <Assembly> CopyDllToExecutionPath(bool withCleanUp,
                                                                 ref List <Tuple <Assembly, Type> > loadedModuleAssemblies,
                                                                 ref List <Assembly> allLoadedAssemblies)
        {
            var moduleDirectoryAssemblies = new List <Assembly>();

            // Clean and create Bin module path
            if (Directory.Exists(ModuleBinDirectoryPath) && withCleanUp)
            {
                SafeRemovePath(ModuleBinDirectoryPath);
            }

            string currentModulePathBinDirectory = CurrentModuleBinDirectoryPath;

            Directory.CreateDirectory(currentModulePathBinDirectory);

            // Modules Dll
            List <KeyValuePair <string, Tuple <FileInfo[], string[]> > > dllmodules =
                Directory.GetDirectories(ModuleDirectoryPath, "*.*", SearchOption.TopDirectoryOnly)
                .Select(dir => new DirectoryInfo(dir))
                .Where(dir => !dir.Name.EndsWith(".svn"))
                .Where(dir => !dir.Name.EndsWith("Bin"))
                .Select(
                    dir =>
                    new KeyValuePair <string, Tuple <FileInfo[], string[]> >(dir.Name,
                                                                             new Tuple <FileInfo[], string[]>(
                                                                                 dir.GetFiles("*.dll"),
                                                                                 GetModuleDependencies(dir))))
                .Where(m => !IsFilteredOut(m))
                .ToList();

            //TODO: Refactorer... il se peut qu'on essaye d'ajouter un dll (dépendance d'un module) alors qu'on réfère déjà cette dépendence...!

            var notYetLoadedModules = new Dictionary <string, Tuple <FileInfo[], string[]> >();
            var dependencyManager   = new DependencyManager();

            foreach (var mod in dllmodules)
            {
                Tuple <Assembly, Type> loaded =
                    loadedModuleAssemblies.FirstOrDefault(
                        q => q.Item1.GetName().Name.Equals(mod.Key, StringComparison.OrdinalIgnoreCase));

                if (loaded == null)
                {
                    notYetLoadedModules.Add(mod.Key, mod.Value);
                }

                dependencyManager.Add(mod.Key, mod.Value.Item2);
            }

            //TODO: Faire en sorte qu'une erreur précise découle d'une dépendences manquantes ou circulaire, etc..

            IEnumerable <string> sortedDependencies = dependencyManager.GetSortedDependencies();

            foreach (string sortedDependency in sortedDependencies)
            {
                Tuple <FileInfo[], string[]> module;

                notYetLoadedModules.TryGetValue(sortedDependency, out module);

                if (module != null)
                {
                    List <FileInfo> dlls = module.Item1.ToList();

                    foreach (FileInfo dll in dlls)
                    {
                        string src = Path.Combine(currentModulePathBinDirectory, dll.Name);

                        if (!File.Exists(src))
                        {
                            File.Copy(dll.FullName, src);
                            Assembly assembly = Assembly.LoadFile(src);
                            allLoadedAssemblies.Add(assembly);
                        }
                    }

                    Assembly moduleAssembly    = allLoadedAssemblies.First(a => a.GetName().Name == sortedDependency);
                    Type     moduleInitializer = ModuleUtilities.GetModuleInitializerFromAssembly(moduleAssembly);
                    loadedModuleAssemblies.Add(new Tuple <Assembly, Type>(moduleAssembly, moduleInitializer));
                    moduleDirectoryAssemblies.Add(moduleAssembly);
                }
            }

            return(moduleDirectoryAssemblies);
        }