public string RenderBreadcrumbInterfaceMethodDeclaration(BreadcrumbMethodDeclaration breadcrumbMethodDeclaration) { var stringTemplate = _serviceCommandGroupFile.GetInstanceOf( StgBreadcrumbCommand.BreadcrumbInterfaceMethodDeclaration.Name); stringTemplate.Add( StgBreadcrumbCommand.BreadcrumbInterfaceMethodDeclaration.Params.ControllerRoot, breadcrumbMethodDeclaration.ControllerRoot); stringTemplate.Add( StgBreadcrumbCommand.BreadcrumbInterfaceMethodDeclaration.Params.Action, breadcrumbMethodDeclaration.Action); stringTemplate.Add( StgBreadcrumbCommand.BreadcrumbInterfaceMethodDeclaration.Params.HasId, breadcrumbMethodDeclaration.HasId); stringTemplate.Add( StgBreadcrumbCommand.BreadcrumbInterfaceMethodDeclaration.Params.Controller, breadcrumbMethodDeclaration.Controller); stringTemplate.Add( StgBreadcrumbCommand.BreadcrumbInterfaceMethodDeclaration.Params.ControllerNamePattern, breadcrumbMethodDeclaration.ControllerNamePattern); return(stringTemplate.Render()); }
public Task Execute(BreadcrumbCommand breadcrumbCommand) { var areaRootNamespace = _projectEnvironment.Value.RootNamespace + (breadcrumbCommand.Area is null || breadcrumbCommand.Area.TrimEnd(@"/\ ".ToCharArray()) == string.Empty ? string.Empty : $".Areas.{breadcrumbCommand.Area.TrimEnd(@"/\ ".ToCharArray())}"); var controllerRootNamespace = areaRootNamespace + ".Controllers"; var breadcrumbRootNamespace = areaRootNamespace + "." + (breadcrumbCommand?.BreadcrumbServiceDirectory?.TrimEnd(@"/\ ".ToCharArray()) ?? "Services.Breadcrumbs" ).Replace("/", ".").Replace(@"\", "."); var defaultAreaBreadcrumbServiceRootName = _projectEnvironment.Value.RootNamespace + (breadcrumbCommand.Area is null || breadcrumbCommand.Area.TrimEnd(@"/\ ".ToCharArray()) == string.Empty ? string.Empty : breadcrumbCommand.Area.TrimEnd(@"/\ ".ToCharArray())) + "Breadcrumb"; var defaultAreaBreadcrumbServiceName = defaultAreaBreadcrumbServiceRootName + "Service"; var commandRootDirectory = Path.Combine( _projectEnvironment.Value.RootDirectory, (breadcrumbCommand.Area is null || breadcrumbCommand.Area.TrimEnd(@"/\ ".ToCharArray()) == string.Empty ? string.Empty : Path.Combine("Areas", breadcrumbCommand.Area))); var targetDirectory = Path.Combine( commandRootDirectory, breadcrumbCommand.TargetDirectory ?? "Controllers"); var breadcrumbOutputDirectory = Path.Combine( commandRootDirectory, breadcrumbCommand?.BreadcrumbServiceDirectory ?? "Services/Breadcrumbs"); Directory.CreateDirectory(breadcrumbOutputDirectory); if (!Directory.Exists(targetDirectory)) { _logger.LogError($"TargetDirectory does not exist at {targetDirectory}"); // throw return(Task.CompletedTask); } var filenames = new List <string>(); if (breadcrumbCommand.TargetFile != null) { var targetFile = Path.Combine(targetDirectory, breadcrumbCommand.TargetFile); if (!File.Exists(targetFile)) { _logger.LogError($"TargetFile does not exist at {targetFile}"); // throw return(Task.CompletedTask); } filenames.Add(targetFile); _logger.LogDebug("Service interface file was already up to date."); } else { filenames = GetCSharpFilesInDirectory(targetDirectory, breadcrumbCommand.IsRecursive ?? false); } var controllerDict = new ControllerDictionary(); foreach (var filename in filenames) { var controllerParser = new CSharpParserWrapper(GetPathFromWrittenTo(filename)); var tree = controllerParser.GetParseTree(); var visitor = _breadcrumbControllerScraperFactory.Create( controllerParser.Tokens); visitor.Visit(tree); var scraperResults = visitor.Results; foreach (var nameKey in scraperResults.NamespaceDict.Keys) { if (controllerDict.NamespaceDict.ContainsKey(nameKey)) { foreach (var classKey in scraperResults.NamespaceDict[nameKey].ClassDict.Keys) { controllerDict.NamespaceDict[nameKey].ClassDict[classKey] = scraperResults.NamespaceDict[nameKey].ClassDict[classKey]; } } else { controllerDict.NamespaceDict[nameKey] = scraperResults.NamespaceDict[nameKey]; } } } //public class InjectedService //{ // public string Type { get; set; } // public string ServiceIdentifier { get; set; } // public string Namespace { get; set; } //} var usingDirectives = new HashSet <string>() { "SmartBreadcrumbs.Nodes" }; var fieldDeclarations = new List <FieldDeclaration>(); var ctorParameters = new FormalParameterList(); var fixedParams = ctorParameters.FixedParameters; var ctorBody = new ConstructorBody(); var statements = ctorBody.Statements; foreach (var injectedService in breadcrumbCommand.InjectedServices) { var injectedServiceIdentifier = injectedService.ServiceIdentifier ?? Regex.Replace( Regex.Replace( injectedService.Type, @"^I?([A-Z])", "$1"), @"^[A-Z]", m => m.ToString().ToLower()); if (!Regex.Match(breadcrumbRootNamespace, "^" + Regex.Escape(injectedService.Namespace)).Success) { usingDirectives.Add(injectedService.Namespace); } fieldDeclarations.Add( new FieldDeclaration() { Modifiers = new List <string>() { Keywords.Private, Keywords.Readonly }, Type = injectedService.Type, VariableDeclarator = new VariableDeclarator() { Identifier = "_" + injectedServiceIdentifier } }); fixedParams.Add( new FixedParameter() { Type = injectedService.Type, Identifier = injectedServiceIdentifier }); statements.Add( new Statement() { SimpleAssignment = new SimpleAssignment() { LeftHandSide = "_" + injectedServiceIdentifier, RightHandSide = injectedServiceIdentifier } }); } var startupRegInfoList = new List <StartupRegistrationInfo>(); foreach (var controllerNamespace in controllerDict.NamespaceDict.Values) { var namespaceSuffix = Regex.Replace( controllerNamespace.Namespace, "^" + Regex.Escape(controllerRootNamespace + "."), string.Empty); var serviceNamePrefix = namespaceSuffix.Replace(".", ""); var serviceClassName = serviceNamePrefix == string.Empty ? defaultAreaBreadcrumbServiceRootName : serviceNamePrefix + "BreadcrumbService"; var serviceInterfaceName = $"I{serviceClassName}"; var serviceClassFilename = Path.Combine(breadcrumbOutputDirectory, $"{serviceClassName}.cs"); var serviceInterfaceFilename = Path.Combine(breadcrumbOutputDirectory, $"{serviceInterfaceName}.cs"); var outServiceClassFilename = Path.Combine(breadcrumbOutputDirectory, $"X{serviceClassName}.cs"); var outServiceInterfaceFilename = Path.Combine(breadcrumbOutputDirectory, $"X{serviceInterfaceName}.cs"); startupRegInfoList.Add(new StartupRegistrationInfo() { ServiceNamespace = breadcrumbRootNamespace, ServiceClassType = serviceClassName, ServiceBaseType = serviceInterfaceName, HasTypeParameters = false, ServiceLifespan = ServiceLifetime.Scoped }); var classDeclaration = new BreadcrumbServiceDeclaration() { IsInterface = false, Modifiers = new List <string>() { Keywords.Public }, Identifier = serviceClassName, Base = new ClassInterfaceBase() { InterfaceTypeList = new List <string>() { serviceInterfaceName } }, Body = new BreadcrumbServiceBody() { FieldDeclarations = fieldDeclarations, ConstructorDeclaration = new ConstructorDeclaration() { Modifiers = new List <string>() { Keywords.Public }, Identifier = serviceClassName, FormalParameterList = ctorParameters, Body = ctorBody } } }; var interfaceDeclaration = new BreadcrumbServiceDeclaration() { IsInterface = true, Identifier = serviceInterfaceName }; foreach (var controllerClass in controllerNamespace.ClassDict.Values) { var controllerNamePattern = breadcrumbCommand.ControllerNamePattern?.Replace( "$ControllerType$", controllerClass.Controller) ?? $"\"{Regex.Replace(controllerClass.Controller, "Controller$", string.Empty)}\""; foreach (var controllerAction in controllerClass.ActionDict.Values) { var methodDeclaration = new BreadcrumbMethodDeclaration() { ControllerRoot = controllerClass.ControllerRoot, Action = controllerAction.Action, HasId = controllerAction.HasId, Controller = controllerClass.Controller, ControllerNamePattern = controllerNamePattern }; classDeclaration.Body.MethodDeclarations.Add(methodDeclaration); interfaceDeclaration.Body.MethodDeclarations.Add(methodDeclaration); } } if (!File.Exists(serviceClassFilename)) { var cos = _breadcrumbCommandStgService.RenderBreadcrumbServiceFile( usingDirectives.ToList(), breadcrumbRootNamespace, classDeclaration); _ioUtilService.WriteStringToFile( cos, outServiceClassFilename); UpdateWrittenTo(serviceClassFilename, outServiceClassFilename); var ios = _breadcrumbCommandStgService.RenderBreadcrumbServiceFile( usingDirectives.ToList(), breadcrumbRootNamespace, interfaceDeclaration); _ioUtilService.WriteStringToFile( ios, outServiceInterfaceFilename); UpdateWrittenTo(serviceInterfaceFilename, outServiceInterfaceFilename); } else { var breadcrumbClassParser = new CSharpParserWrapper( GetPathFromWrittenTo( Path.Combine(breadcrumbOutputDirectory, serviceClassFilename))); var tree = breadcrumbClassParser.GetParseTree(); var visitor = _breadcrumbClassInjectorFactory.Create( breadcrumbClassParser.Tokens, usingDirectives.ToList(), breadcrumbRootNamespace, classDeclaration, _userSettings.Value.TabString); visitor.Visit(tree); if (visitor.IsModified) { _ioUtilService.WriteStringToFile( visitor.Rewriter.GetText(), outServiceClassFilename); UpdateWrittenTo(serviceClassFilename, outServiceClassFilename); } var serviceClassParser = new CSharpParserWrapper(GetPathFromWrittenTo(serviceClassFilename)); var classScraperResults = _serviceCommandService.ScrapeServiceClass( serviceClassParser, serviceClassName, breadcrumbRootNamespace, null); _ioUtilService.WriteStringToFile( _serviceCommandService.GetInterfaceServiceFileFromClass( classScraperResults, serviceInterfaceName, breadcrumbRootNamespace), outServiceInterfaceFilename); UpdateWrittenTo(serviceInterfaceFilename, outServiceInterfaceFilename); } } RegisterServicesInStartup(startupRegInfoList); InjectBreadcrumbsIntoControllers(controllerFilepaths: filenames, controllerDictionary: controllerDict, breadcrumbServiceNamespace: breadcrumbRootNamespace, controllerRootNamespace: controllerRootNamespace, defaultAreaBreadcrumbServiceRootName: defaultAreaBreadcrumbServiceRootName, tabString: _userSettings.Value.TabString); return(Task.CompletedTask); }