private async Task WriteDbContext(NewDbContextTemplateModel dbContextTemplateModel, SyntaxTree newDbContextTree) { //ToDo: What's the best place to write the DbContext? var appBasePath = _environment.ApplicationBasePath; var outputPath = Path.Combine( appBasePath, "Models", dbContextTemplateModel.DbContextTypeName + ".cs"); if (File.Exists(outputPath)) { // Odd case, a file exists with the same name as the DbContextTypeName but perhaps // the type defined in that file is different, what should we do in this case? // How likely is the above scenario? // Perhaps we can enumerate files with prefix and generate a safe name? For now, just throw. throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, "There was an error creating a DbContext, the file {0} already exists", outputPath)); } var sourceText = await newDbContextTree.GetTextAsync(); Directory.CreateDirectory(Path.GetDirectoryName(outputPath)); using (var fileStream = new FileStream(outputPath, FileMode.CreateNew, FileAccess.Write)) { using (var streamWriter = new StreamWriter(stream: fileStream, encoding: Encoding.UTF8)) { sourceText.Write(streamWriter); } } _logger.LogMessage("Added DbContext : " + outputPath.Substring(appBasePath.Length)); }
public async Task <SyntaxTree> AddNewContext([NotNull] NewDbContextTemplateModel dbContextTemplateModel) { var templateName = "NewLocalDbContext.cshtml"; var templatePath = _filesLocator.GetFilePath(templateName, TemplateFolders); Contract.Assert(File.Exists(templatePath)); var templateContent = File.ReadAllText(templatePath); var templateResult = await _templatingService.RunTemplateAsync(templateContent, dbContextTemplateModel); if (templateResult.ProcessingException != null) { throw new InvalidOperationException(string.Format( "There was an error running the template {0}: {1}", templatePath, templateResult.ProcessingException.Message)); } var newContextContent = templateResult.GeneratedText; var sourceText = SourceText.From(newContextContent); return(CSharpSyntaxTree.ParseText(sourceText)); }
public async Task <ModelMetadata> GetModelMetadata(string dbContextTypeName, ModelType modelTypeSymbol) { Type dbContextType; var dbContextSymbols = _modelTypesLocator.GetType(dbContextTypeName).ToList(); var isNewDbContext = false; SyntaxTree newDbContextTree = null; NewDbContextTemplateModel dbContextTemplateModel = null; if (dbContextSymbols.Count == 0) { isNewDbContext = true; await ValidateEFSqlServerDependency(); _logger.LogMessage("Generating a new DbContext class " + dbContextTypeName); dbContextTemplateModel = new NewDbContextTemplateModel(dbContextTypeName, modelTypeSymbol); newDbContextTree = await _dbContextEditorServices.AddNewContext(dbContextTemplateModel); _logger.LogMessage("Attempting to compile the application in memory with the added DbContext"); var projectCompilation = _libraryManager.GetProject(_environment).Compilation; var newAssemblyName = projectCompilation.AssemblyName + _counter++; var newCompilation = projectCompilation.AddSyntaxTrees(newDbContextTree).WithAssemblyName(newAssemblyName); var result = CommonUtilities.GetAssemblyFromCompilation(_loader, newCompilation); if (result.Success) { dbContextType = result.Assembly.GetType(dbContextTypeName); if (dbContextType == null) { throw new InvalidOperationException("There was an error creating a DbContext, there was no type returned after compiling the new assembly successfully"); } } else { throw new InvalidOperationException("There was an error creating a DbContext :" + string.Join("\n", result.ErrorMessages)); } } else { dbContextType = _libraryManager.GetReflectionType(_environment, dbContextTypeName); if (dbContextType == null) { throw new InvalidOperationException("Could not get the reflection type for DbContext : " + dbContextTypeName); } } var modelTypeName = modelTypeSymbol.FullName; var modelType = _libraryManager.GetReflectionType(_environment, modelTypeName); if (modelType == null) { throw new InvalidOperationException("Could not get the reflection type for Model : " + modelTypeName); } _logger.LogMessage("Attempting to figure out the EntityFramework metadata for the model and DbContext"); var metadata = GetModelMetadata(dbContextType, modelType); // Write the DbContext if getting the model metadata is successful if (isNewDbContext) { await WriteDbContext(dbContextTemplateModel, newDbContextTree); } return(metadata); }
public async Task<ModelMetadata> GetModelMetadata(string dbContextTypeName, ModelType modelTypeSymbol) { Type dbContextType; var dbContextSymbols = _modelTypesLocator.GetType(dbContextTypeName).ToList(); var isNewDbContext = false; SyntaxTree newDbContextTree = null; NewDbContextTemplateModel dbContextTemplateModel = null; if (dbContextSymbols.Count == 0) { isNewDbContext = true; await ValidateEFSqlServerDependency(); _logger.LogMessage("Generating a new DbContext class " + dbContextTypeName); dbContextTemplateModel = new NewDbContextTemplateModel(dbContextTypeName, modelTypeSymbol); newDbContextTree = await _dbContextEditorServices.AddNewContext(dbContextTemplateModel); _logger.LogMessage("Attempting to compile the application in memory with the added DbContext"); var projectCompilation = _libraryManager.GetProject(_environment).Compilation; var newAssemblyName = projectCompilation.AssemblyName + _counter++; var newCompilation = projectCompilation.AddSyntaxTrees(newDbContextTree).WithAssemblyName(newAssemblyName); var result = CommonUtilities.GetAssemblyFromCompilation(_loader, newCompilation); if (result.Success) { dbContextType = result.Assembly.GetType(dbContextTypeName); if (dbContextType == null) { throw new InvalidOperationException("There was an error creating a DbContext, there was no type returned after compiling the new assembly successfully"); } } else { throw new InvalidOperationException("There was an error creating a DbContext :" + string.Join("\n", result.ErrorMessages)); } } else { dbContextType = _libraryManager.GetReflectionType(_environment, dbContextTypeName); if (dbContextType == null) { throw new InvalidOperationException("Could not get the reflection type for DbContext : " + dbContextTypeName); } } var modelTypeName = modelTypeSymbol.FullName; var modelType = _libraryManager.GetReflectionType(_environment, modelTypeName); if (modelType == null) { throw new InvalidOperationException("Could not get the reflection type for Model : " + modelTypeName); } _logger.LogMessage("Attempting to figure out the EntityFramework metadata for the model and DbContext"); var metadata = GetModelMetadata(dbContextType, modelType); // Write the DbContext if getting the model metadata is successful if (isNewDbContext) { await WriteDbContext(dbContextTemplateModel, newDbContextTree); } return metadata; }