private ILoggerBuilderExtension[] CompileAndEvaluateExtensions(ProjectItem projectItem, IEnumerable <ProjectItem> referenceItems)
        {
            LogMessage($"Compiling possible logger builder extension file {projectItem?.Include ?? "in referenced dlls"}");

            var extensions = new List <ILoggerBuilderExtension>();

            try
            {
                var parameters = new CompilerParameters();

                foreach (var referenceItem in referenceItems)
                {
                    parameters.ReferencedAssemblies.Add(referenceItem.Name);
                }

                //parameters.ReferencedAssemblies.Add("System.dll");
                parameters.GenerateExecutable = false;
                parameters.GenerateInMemory   = true;

                parameters.IncludeDebugInformation = false;
                var cSharpCodeProvider = new CSharpCodeProvider();
                //var cSharpCodeProvider = new Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider();

                var             items = projectItem != null ? new string[] { projectItem.Name } : new string[0];
                CompilerResults compilerResults;
                compilerResults = cSharpCodeProvider.CompileAssemblyFromFile(parameters, items);
                foreach (CompilerError compilerResultsError in compilerResults.Errors)
                {
                    LogMessage(compilerResultsError.ToString());
                }

                var types = compilerResults.CompiledAssembly.GetTypes();
                foreach (
                    var type in
                    types.Where(t => typeof(ILoggerBuilderExtension).IsAssignableFrom(t)))
                {
                    var extension = (ILoggerBuilderExtension)Activator.CreateInstance(type);
                    extensions.Add(extension);
                }
            }
            catch (Exception ex)
            {
                LogMessage($"Failed to compile/evaluate {projectItem.Include} - {ex.Message}\r\n{ex.StackTrace}");
            }
            return(extensions.ToArray());
        }
        private IEnumerable <ProjectItem> GenerateEventSourceCode(string projectBasePath, ProjectItem projectItem, EventSourcePrototype eventSourcePrototype, LoggerTemplateModel[] loggers, ILoggerBuilderExtension[] extensions)
        {
            eventSourcePrototype.AvailableLoggers  = loggers;
            eventSourcePrototype.BuilderExtensions = extensions;
            var outputs = eventSourcePrototype.Render(projectBasePath);

            var eventSourceProjectItems = new List <ProjectItem>();

            foreach (var output in outputs)
            {
                output.DependentUpon = projectItem;
                eventSourceProjectItems.Add(output);
            }
            return(eventSourceProjectItems);
        }
        private IEnumerable <ProjectItem> GenerateEventSourceCode(string projectBasePath, ProjectItem projectItem, LoggerTemplateModel[] loggers, ILoggerBuilderExtension[] extensions)
        {
            var sourceFileName         = System.IO.Path.GetFileName(projectItem.Name);
            var implementationFileName = $"{System.IO.Path.GetFileNameWithoutExtension(projectItem.Name)}.cs";
            var fileRelativePath       = projectItem.Name.RemoveFromStart(projectBasePath + System.IO.Path.DirectorySeparatorChar).Replace(sourceFileName, implementationFileName);

            var fileRelateiveFolderPath = System.IO.Path.GetDirectoryName(fileRelativePath);
            var eventSourceNamespace    = $"{projectItem.RootNamespace}.{fileRelateiveFolderPath.Replace(System.IO.Path.DirectorySeparatorChar, '.')}";

            var content = System.IO.File.ReadAllText(projectItem.Name);
            var eventSourcePrototype = Newtonsoft.Json.JsonConvert.DeserializeObject <EventSourcePrototype>(content);

            var fileName  = System.IO.Path.GetFileName(projectItem.Name);
            var className = System.IO.Path.GetFileNameWithoutExtension(fileName);

            eventSourcePrototype.ClassName      = className;
            eventSourcePrototype.Include        = fileRelativePath;
            eventSourcePrototype.SourceFilePath = projectItem.Include;
            eventSourcePrototype.Namespace      = eventSourceNamespace;
            return(GenerateEventSourceCode(projectBasePath, projectItem, eventSourcePrototype, loggers, extensions));
        }
        private LoggerTemplateModel[] CompileAndEvaluateInterface(ProjectItem projectItem, IEnumerable <ProjectItem> referenceItems)
        {
            LogMessage($"Compiling possible logger file {projectItem.Include}");

            var loggers = new List <EventSourceLoggerTemplate>();

            try
            {
                var parameters = new CompilerParameters();

                foreach (var referenceItem in referenceItems)
                {
                    parameters.ReferencedAssemblies.Add(referenceItem.Name);
                }

                //parameters.ReferencedAssemblies.Add("System.dll");
                parameters.GenerateExecutable = false;
                parameters.GenerateInMemory   = true;

                parameters.IncludeDebugInformation = false;
                var cSharpCodeProvider = new CSharpCodeProvider();
                //var cSharpCodeProvider = new Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider();
                var compilerResults = cSharpCodeProvider.CompileAssemblyFromFile(parameters, projectItem.Name);
                foreach (CompilerError compilerResultsError in compilerResults.Errors)
                {
                    LogMessage(compilerResultsError.ToString());
                }

                var types = compilerResults.CompiledAssembly.GetTypes();
                foreach (
                    var type in
                    types.Where(t => t.IsInterface && t.Name.Matches(@"^I[^\\]*Logger", StringComparison.InvariantCultureIgnoreCase, useWildcards: false)))
                {
                    var include           = projectItem.Include.Replace(projectItem.Name, type.Name);
                    var eventSourceLogger = new EventSourceLoggerTemplate()
                    {
                        Name      = type.Name,
                        Namespace = type.Namespace,
                        Include   = include
                    };
                    var eventSourceEvents = new List <EventModel>();
                    foreach (var methodInfo in type.GetMethods())
                    {
                        var eventSourceEventArguments = new List <EventSourceEventArgument>();
                        var eventSourceEvent          = new EventSourceEvent()
                        {
                            Name = methodInfo.Name,
                        };
                        foreach (var parameterInfo in methodInfo.GetParameters())
                        {
                            var typeString = parameterInfo.ParameterType.GetFriendlyName();
                            eventSourceEventArguments.Add(new EventSourceEventArgument()
                            {
                                Name = parameterInfo.Name,
                                Type = typeString,
                            });
                        }
                        eventSourceEvent.Arguments = eventSourceEventArguments.ToArray();
                        eventSourceEvents.Add(eventSourceEvent);
                    }

                    eventSourceLogger.Events = eventSourceEvents.ToArray();
                    loggers.Add(eventSourceLogger);
                }
            }
            catch (Exception ex)
            {
                LogMessage($"Failed to compile/evaluate {projectItem.Include} - {ex.Message}\r\n{ex.StackTrace}");
            }
            return(loggers.ToArray());
        }