Ejemplo n.º 1
0
        private Assembly OnCurrentDomainAssemblyResolve(object sender, ResolveEventArgs e)
        {
            if (e.RequestingAssembly == null)
            {
                return(null);
            }

            AssemblyName assemblyName = new AssemblyName(e.Name);

            if (assemblyName.Name.EndsWith(".resources", StringComparison.InvariantCultureIgnoreCase) &&
                !assemblyName.CultureName.EndsWith("neutral", StringComparison.InvariantCultureIgnoreCase))
            {
                return(null);
            }

            // Try to load the dependencies located to the temp directory...

            string tmpPath = Path.Combine(Path.GetTempPath(), "LayerCake Generator", this.Context.ProjectName);

            FileInfo[] files = new DirectoryInfo(tmpPath).GetFiles(string.Format("{0}.*.dll", assemblyName.Name));
            FileInfo   file  = files.First(i => i.CreationTimeUtc == files.Max(j => j.CreationTimeUtc));

            string requiredAssemblyPath = Path.Combine(tmpPath, file.Name);

            ProxyDomain proxyDomain = new ProxyDomain();
            Assembly    assembly    = proxyDomain.LoadAssembly(requiredAssemblyPath, withPdbSymbols: true);

            return(assembly);
        }
        protected override void BeginProcessing()
        {
            base.BeginProcessing();

            if (path.StartsWith(@".\"))
            {
                path = System.IO.Path.Combine(this.CurrentProviderLocation("FileSystem").ProviderPath, path.Substring(2));
            }
            else
            {
                path = System.IO.Path.Combine(this.CurrentProviderLocation("FileSystem").ProviderPath, path);
            }

            path = System.IO.Path.GetFullPath(path);

            if (!System.IO.File.Exists(path))
            {
                ThrowTerminatingError(new ErrorRecord(new FileNotFoundException(string.Format("File {0} not found", path)), "100", ErrorCategory.OpenError, path));
            }



            string         domainName     = "GetSelfHostedPSDomain-" + Guid.NewGuid().ToString().GetHashCode().ToString("x");
            Evidence       domainEvidence = new Evidence(AppDomain.CurrentDomain.Evidence);
            AppDomainSetup domainInfo     = new AppDomainSetup();

            domainInfo.ApplicationName = domainName;
            domainInfo.ApplicationBase = System.IO.Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);

            AppDomain subDomain = AppDomain.CreateDomain(domainName, domainEvidence, domainInfo);
            Type      type      = typeof(ProxyDomain);

            ProxyDomain proxyDomain = (ProxyDomain)subDomain.CreateInstanceAndUnwrap(type.Assembly.FullName, type.FullName);

            proxyDomain.LoadAssembly(GetDLLLocation("System"));
            proxyDomain.LoadAssembly(GetDLLLocation("System.Management"));
            proxyDomain.LoadAssembly(GetDLLLocation("System.Management.Automation"));
            proxyDomain.LoadAssembly(Assembly.GetExecutingAssembly().Location);

            WriteObject(proxyDomain.GetAssembly(path));

            AppDomain.Unload(subDomain);
            subDomain = null;
        }
Ejemplo n.º 3
0
        public void Execute(IProcessorBehavior behavior, ProcessorParameters parameters)
        {
            if (this.IsRunning)
            {
                ThrowException.Throw("The processor is already running");
            }

            do
            {
                #region [ Begin ]

                this.IsRunning = true;

                _stopwatch = new Stopwatch();
                _stopwatch.Start();

                if (this.CancelToken != null)
                {
                    this.CancelToken.Dispose();
                }

                this.CancelToken       = new CancellationTokenSource();
                this.GeneratedServices = new List <string>();

                this.HasErrors = false;

                this.PublishProcessMessage("Running Process ({0} mode)...", parameters.CompilationMode);

                #endregion

                #region [ Checking Assemblies Dependencies ]

                if (this.CancelToken.IsCancellationRequested)
                {
                    break;
                }

                this.PublishProcessMessage("Checking Assemblies Dependencies...");

                bool bOk = true;

                string modelAssemblyPath = Path.Combine(this.Context.SrcDirectory,
                                                        string.Format(@"{0}.Models", this.Context.ProjectName),
                                                        string.Format(@"bin\{0}", parameters.CompilationMode),
                                                        string.Format(@"{0}.Models.dll", this.Context.ProjectName));

                if (!File.Exists(modelAssemblyPath))
                {
                    bOk = false;
                }

                if (bOk)
                {
                    string businessAssemblyPath = Path.Combine(this.Context.SrcDirectory,
                                                               string.Format(@"{0}.Business", this.Context.ProjectName),
                                                               string.Format(@"bin\{0}", parameters.CompilationMode),
                                                               string.Format(@"{0}.Business.dll", this.Context.ProjectName));

                    if (!File.Exists(businessAssemblyPath))
                    {
                        bOk = false;
                    }
                }

                if (!bOk)
                {
                    this.PublishErrorMessage(
                        "The whole solution must be compiled ({0} mode) before running the proccess.",
                        parameters.CompilationMode);

                    break;
                }

                #endregion

                #region [ Checking and Loading Culture Context ]

                if (this.CancelToken.IsCancellationRequested)
                {
                    break;
                }

                this.PublishProcessMessage("Checking and Loading Culture Context...");

                string[] supportedCultures = DatabaseHelper.GetCultures(this.SmoContext);
                this.Context.Culture.SupportedCultures = supportedCultures;

                if (this.Context.Culture.SupportedCultures.Length == 0)
                {
                    this.PublishErrorMessage("The 'Translation' table must define at least one culture!");

                    break;
                }

                foreach (string culture in supportedCultures.Where(c => c.Length != 2))
                {
                    this.PublishErrorMessage(
                        "The '{0}' culture column from the 'Translation' table is not correct! Culture columns must be 2 characters long.",
                        culture);

                    break;
                }

                if (!supportedCultures.Contains(this.Context.Culture.Default))
                {
                    this.PublishErrorMessage(
                        "The default culture '{0}' is not supported ({1}).",
                        this.Context.Culture.Default, string.Join(", ", supportedCultures));

                    break;
                }

                #endregion

                #region [ Checking and Loading Database Structure ]

                if (this.CancelToken.IsCancellationRequested)
                {
                    break;
                }

                this.PublishProcessMessage("Checking and Loading Database Structure...");

                this.ModelDescriptor = new ModelDescriptor(this.SmoContext, this.Context);

                string mdFile = null;

                try
                {
                    mdFile = this.ModelDescriptor.Load(this.CancelToken.Token);
                }
                catch (Exception x)
                {
                    this.PublishErrorMessage(
                        "Failed while loading Database Structure (Table: '{1}' - Column: '{2}') -> {0}",
                        x, this.ModelDescriptor.CurrentTable.Name, this.ModelDescriptor.CurrentColumn.Name);

                    break;
                }

                if (this.CancelToken.IsCancellationRequested)
                {
                    break;
                }

                if (this.ModelDescriptor.Errors.Count != 0)
                {
                    foreach (var error in this.ModelDescriptor.Errors)
                    {
                        this.PublishErrorMessage(error.GetError());
                    }

                    break;
                }

                #endregion

                #region [ Checking Authentication Support ]

                if (this.CancelToken.IsCancellationRequested)
                {
                    break;
                }

                var userTable = this.ModelDescriptor.Schema.Tables.FirstOrDefault(t => t.Name == this.Context.AuthenticationSupport.UserTableName);
                if (userTable == null)
                {
                    this.PublishErrorMessage(
                        "The '{0}' table declared in Context.AuthenticationSupport.UserTableName cannot be found in the database!",
                        this.Context.AuthenticationSupport.UserTableName);

                    break;
                }
                else
                {
                    if (userTable.Columns.Count(c => c.Name == this.Context.AuthenticationSupport.UserTableIdentifiedColumnName) == 0)
                    {
                        this.PublishErrorMessage(
                            "The '{0}' table must have a column named '{1}'!",
                            this.Context.AuthenticationSupport.UserTableName,
                            this.Context.AuthenticationSupport.UserTableIdentifiedColumnName);

                        break;
                    }

                    // UserTableIdentifiedColumnName must have an UNIQUE constraint...
                    if (userTable.Constraints == null || userTable.Constraints.Count(c => c.Columns.Any(i => i.Name == this.Context.AuthenticationSupport.UserTableIdentifiedColumnName)) == 0)
                    {
                        this.PublishErrorMessage(
                            "The '{0}' column from the '{1}' table must have an UNIQUE constraint in order to be used as identifier column!",
                            this.Context.AuthenticationSupport.UserTableIdentifiedColumnName,
                            this.Context.AuthenticationSupport.UserTableName);


                        break;
                    }

                    // UserTableName must define Password & Culture columns
                    if (userTable.Columns.Count(c => c.CSharpPropertyName == "Password") == 0 || userTable.Columns.Count(c => c.CSharpPropertyName == "Culture") == 0)
                    {
                        this.PublishErrorMessage(
                            "The '{0}' table must have '{0}_Password' and '{0}_Culture' columns!",
                            this.Context.AuthenticationSupport.UserTableName);

                        break;
                    }
                }

                #endregion

                #region [ Loading Assemblies Dependencies ]

                if (this.CancelToken.IsCancellationRequested)
                {
                    break;
                }

                this.PublishProcessMessage("Loading Assemblies Dependencies...");

                Assembly businessAssembly = null;

                try
                {
                    string tmpDir = Path.Combine(Path.GetTempPath(), "LayerCake Generator", this.Context.ProjectName);
                    if (!Directory.Exists(tmpDir))
                    {
                        Directory.CreateDirectory(tmpDir);
                    }

                    foreach (FileInfo file in new DirectoryInfo(tmpDir).GetFiles())
                    {
                        string extension = file.Extension.ToLowerInvariant();
                        if (extension == ".dll" || extension == ".pdb")
                        {
                            try
                            {
                                file.Delete();
                            }
                            catch (UnauthorizedAccessException)
                            {
                                // Occurred when the assembly is already loaded in the AppDomain.CurrentDomain
                            }
                            catch (Exception)
                            {
                            }
                        }
                    }

                    string guid = Guid.NewGuid().ToString();

                    string assemblyPath = Path.GetDirectoryName(
                        this.Context.GetAssemblyPath("Business", parameters.CompilationMode));

                    if (!Directory.Exists(assemblyPath))
                    {
                        this.PublishErrorMessage("Cannot locate the path {0}", assemblyPath);

                        break;
                    }

                    string      businessAssemblyPath = null;
                    ProxyDomain proxyDomain          = new ProxyDomain();

                    // Copy all DLL/PDB files from the Business\bin\Debug to the Temp...

                    foreach (FileInfo file in new DirectoryInfo(assemblyPath).GetFiles())
                    {
                        string extension = file.Extension.ToLowerInvariant();
                        if (extension == ".dll" || extension == ".pdb")
                        {
                            string copiedDllPath = Path.Combine(tmpDir, string.Format("{0}.{1}{2}", Path.GetFileNameWithoutExtension(file.Name), guid, extension));
                            File.Copy(file.FullName, copiedDllPath);

                            if (copiedDllPath.Contains(".Business") && Path.GetExtension(copiedDllPath).ToLowerInvariant() == ".dll")
                            {
                                businessAssemblyPath = copiedDllPath;
                            }
                        }
                    }

                    // Must be at the end once all the DLLs have been copied.
                    // (cf. AppDomain Assembly Resolving (Program.cs, CurrentDomain_AssemblyResolve))...
                    businessAssembly = proxyDomain.LoadAssembly(businessAssemblyPath);
                }
                catch (Exception x)
                {
                    this.PublishErrorMessage(
                        "Cannot load Assemblies Dependencies -> {0}",
                        x.GetFullMessage(withExceptionType: true));

                    break;
                }

                #endregion

                #region [ Loading Business Context ]

                if (this.CancelToken.IsCancellationRequested)
                {
                    break;
                }

                this.PublishProcessMessage("Loading Business Context...");

                IList <string> errors;
                this.BusinessContext = new BusinessContext(businessAssembly);

                try
                {
                    this.BusinessContext.Load(out errors);
                }
                catch (Exception x)
                {
                    this.PublishErrorMessage("Cannot load the Business Context -> {0}", x.Message);

                    break;
                }

                if (errors.Count != 0)
                {
                    foreach (string error in errors)
                    {
                        this.PublishErrorMessage(error);
                    }

                    break;
                }

                #endregion

                #region [ Creating TextTemplating TextTemplatingEngine ]

                if (this.CancelToken.IsCancellationRequested)
                {
                    break;
                }

                this.PublishProcessMessage("Creating TextTemplating Engine...");

                this.TextTemplatingEngine = new TextTemplatingEngine(
                    this.Context.SolutionDirectory,
                    this.Context.TemplateDirectory);

                this.TextTemplatingEngine.OnGeneratedFile += OnFileGenerated;

                #endregion

                #region [ Executing... ]

                behavior.Execute(this, parameters);

                #endregion
            }while (false);

            #region [ End ]

            _stopwatch.Stop();

            int nbFiles = this.TextTemplatingEngine != null?this.TextTemplatingEngine.GeneratedFiles.Count() : 0;

            string summary = string.Format("Process Duration -> {0}secs ({1} files)", (int)_stopwatch.Elapsed.TotalSeconds, nbFiles);

            if (this.HasErrors)
            {
                this.PublishErrorMessage("Undo code modifications");
                this.PublishErrorMessage(summary);
            }
            else
            {
                if (this.CancelToken.IsCancellationRequested)                 // the process has been stopped -> do not commit (-> do not call LinkGeneratedFiles())
                {
                    this.PublishErrorMessage("Undo code modifications");      // cancel user action
                }
                else
                {
                    this.LinkGeneratedFiles();
                }

                this.PublishProcessMessage(summary);
            }

            this.Clear();

            this.IsRunning = false;

            #endregion
        }