jake williamson
06/27/2024, 2:08 AMGeneratedCodeAttribute
from the models builder and we're trying to work out what kind of impact this would have?
it came up after reviewing pull requests of umbraco upgrades. as every single generated model is regenerated, not only are our pull requests more bloated than they need to be but it also makes it very hard to spot if the upgrade has changed a property type when it was generated...
when we found the IModelsGenerator
interface in the core https://docs.umbraco.com/umbraco-cms/reference/templating/modelsbuilder/understand-and-extend#imodelsgenerator we threw some code together that strips the attribute out which results in much cleaner models.
based on our experiments, this doesn't impact the running of umbraco but we're wondering if this is a safe thing to do?!
according to msdn:
The GeneratedCodeAttribute class can be used by code analysis tools to identify computer-generated code, and to provide an analysis based on the tool and the version of the tool that generated the code.
we're not running the code through an analysis tool and we know that the umbraco core has generated the code.... so we're happy to live without it if its not strictly needed?
any feedback would be great!jake williamson
06/27/2024, 2:09 AMpublic class SiteModelsGeneratorComposer : IComposer
{
public void Compose(IUmbracoBuilder builder)
{
builder.Services.AddSingleton<IModelsGenerator, SiteModelsGenerator>();
}
}
public class SiteModelsGenerator : IModelsGenerator
{
private readonly IHostingEnvironment _hostingEnvironment;
private ModelsBuilderSettings _config;
public SiteModelsGenerator(IOptionsMonitor<ModelsBuilderSettings> config, IHostingEnvironment hostingEnvironment)
{
_config = config.CurrentValue;
_hostingEnvironment = hostingEnvironment;
config.OnChange(x => _config = x);
}
public void GenerateModels()
{
var modelsDirectory = _config.ModelsDirectoryAbsolute(_hostingEnvironment);
var files = Directory.GetFiles(modelsDirectory);
var generatedByPattern = @"//\s+Umbraco\.ModelsBuilder\.Embedded v[^\s]+";
var generatedCodeAttributePattern = @"\t\t\[global::System\.CodeDom\.Compiler\.GeneratedCodeAttribute\(""Umbraco\.ModelsBuilder\.Embedded"", "".*?""\)\]\r\n";
foreach (var file in files)
{
var content = File.ReadAllText(file);
var contentWithoutGeneratedBy = Regex.Replace(content, generatedByPattern, "// Umbraco.ModelsBuilder.Embedded");
var contentWithoutGeneratedCodeAttribute = Regex.Replace(contentWithoutGeneratedBy, generatedCodeAttributePattern, string.Empty);
File.WriteAllText(file, contentWithoutGeneratedCodeAttribute);
}
}
}
skttl
06/27/2024, 6:57 AMkdx-perbol
06/27/2024, 7:17 AMskttl
06/27/2024, 9:18 AMskttl
06/27/2024, 9:19 AMjake williamson
06/29/2024, 1:11 AMIModelsGenerator
implimentation after the core one meaning the code runs after the core generates the models so any new models are then also manipulated.
good call on the resharper side of things @kdx-perbol that makes sense, we'll give it a try 😉 re the pr clutter, i'm not sure if there's a way to make the compare tool ignore the attribute?
i think you are on to something @skttl - it'd be better to strip out the version rather than the attribute? that way any tools like resharper etc are happy and our prs stay the same?
i'll have a play with this over the weekend and post the updated code 👍
but the impression i'm getting is that there wouldn't be any harm in removing the attribute and/or version number?!jake williamson
07/01/2024, 12:02 AMjake williamson
07/01/2024, 12:02 AM/// <summary>
/// Removes the version number from the generated models making file comparison after Umbraco upgrades easier
/// </summary>
public class SiteModelsGenerator : ModelsGenerator, IModelsGenerator
{
private readonly IHostingEnvironment _hostingEnvironment;
private ModelsBuilderSettings _config;
public SiteModelsGenerator(UmbracoServices umbracoService, IOptionsMonitor<ModelsBuilderSettings> config, OutOfDateModelsStatus outOfDateModels, IHostingEnvironment hostingEnvironment) : base(umbracoService, config, outOfDateModels, hostingEnvironment)
{
_config = config.CurrentValue;
_hostingEnvironment = hostingEnvironment;
config.OnChange(x => _config = x);
}
public new void GenerateModels()
{
base.GenerateModels();
var modelsDirectory = _config.ModelsDirectoryAbsolute(_hostingEnvironment);
var files = Directory.GetFiles(modelsDirectory);
const string generatedByPattern = @"//\s+Umbraco\.ModelsBuilder\.Embedded v[^\s]+";
const string generatedCodeAttributePattern = @"GeneratedCodeAttribute\(""Umbraco\.ModelsBuilder\.Embedded"", "".*?""\)\]";
foreach (var file in files)
{
var content = File.ReadAllText(file);
var contentWithoutGeneratedBy = Regex.Replace(content, generatedByPattern, "// Umbraco.ModelsBuilder.Embedded");
var contentWithoutGeneratedCodeAttribute = Regex.Replace(contentWithoutGeneratedBy, generatedCodeAttributePattern, @"GeneratedCodeAttribute(""Umbraco.ModelsBuilder.Embedded"", """")]");
File.WriteAllText(file, contentWithoutGeneratedCodeAttribute);
}
}
}
jake williamson
07/01/2024, 12:03 AMKaspar Boel Kjeldsen
07/01/2024, 1:24 PMAnders Bjerner
07/01/2024, 4:26 PMappsettings.json
if using our custom Models Builder:
https://packages.limbo.works/limbo.umbraco.modelsbuilder/docs/v13/configuration/#include-version-in-file-headers