From 47202c55d183aec5e9854e800b58d7e56c323dea Mon Sep 17 00:00:00 2001 From: Luiz Henrique Cassettari Date: Fri, 16 May 2025 14:46:15 -0300 Subject: [PATCH 01/38] Add `ModelBase` with custom `IXmlSerializable` --- .../Autodesk.PackageBuilder.Tests.csproj | 4 +- Autodesk.PackageBuilder.sln | 1 + .../Autodesk.PackageBuilder.csproj | 4 - .../Model/Addin/AddInApplication.cs | 2 +- .../Model/Addin/AddInModel.cs | 2 +- .../Model/Addin/RevitAddIns.cs | 2 +- .../Model/Application/ApplicationPackage.cs | 2 +- .../Model/Application/CompanyDetails.cs | 2 +- .../Model/Application/ComponentEntry.cs | 2 +- .../Model/Application/Components.cs | 2 +- .../Model/Application/RuntimeRequirements.cs | 2 +- Autodesk.PackageBuilder/Model/ModelBase.cs | 105 ++++++++++++++++++ .../Model/ModelBaseExtension.cs | 25 +++++ Build/Build.csproj | 2 +- CHANGELOG.md | 8 ++ Directory.Build.props | 5 + 16 files changed, 155 insertions(+), 15 deletions(-) create mode 100644 Autodesk.PackageBuilder/Model/ModelBase.cs create mode 100644 Autodesk.PackageBuilder/Model/ModelBaseExtension.cs create mode 100644 Directory.Build.props diff --git a/Autodesk.PackageBuilder.Tests/Autodesk.PackageBuilder.Tests.csproj b/Autodesk.PackageBuilder.Tests/Autodesk.PackageBuilder.Tests.csproj index 8c77bdb..e3e9840 100644 --- a/Autodesk.PackageBuilder.Tests/Autodesk.PackageBuilder.Tests.csproj +++ b/Autodesk.PackageBuilder.Tests/Autodesk.PackageBuilder.Tests.csproj @@ -8,8 +8,8 @@ - - + + diff --git a/Autodesk.PackageBuilder.sln b/Autodesk.PackageBuilder.sln index ad09bca..ac56445 100644 --- a/Autodesk.PackageBuilder.sln +++ b/Autodesk.PackageBuilder.sln @@ -10,6 +10,7 @@ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Project", "Project", "{F7162A81-C306-4E55-B881-86FFF09FBD5B}" ProjectSection(SolutionItems) = preProject CHANGELOG.md = CHANGELOG.md + Directory.Build.props = Directory.Build.props README.md = README.md EndProjectSection EndProject diff --git a/Autodesk.PackageBuilder/Autodesk.PackageBuilder.csproj b/Autodesk.PackageBuilder/Autodesk.PackageBuilder.csproj index 0919422..ae68a52 100644 --- a/Autodesk.PackageBuilder/Autodesk.PackageBuilder.csproj +++ b/Autodesk.PackageBuilder/Autodesk.PackageBuilder.csproj @@ -6,10 +6,6 @@ latest - - 1.0.6 - - ricaun Luiz Henrique Cassettari diff --git a/Autodesk.PackageBuilder/Model/Addin/AddInApplication.cs b/Autodesk.PackageBuilder/Model/Addin/AddInApplication.cs index 702a624..65636dc 100644 --- a/Autodesk.PackageBuilder/Model/Addin/AddInApplication.cs +++ b/Autodesk.PackageBuilder/Model/Addin/AddInApplication.cs @@ -2,7 +2,7 @@ { using System.Xml; using System.Xml.Serialization; - public class AddInApplication + public class AddInApplication : ModelBase { [XmlAttribute] public string Type { get; set; } diff --git a/Autodesk.PackageBuilder/Model/Addin/AddInModel.cs b/Autodesk.PackageBuilder/Model/Addin/AddInModel.cs index 8db7965..802b0d3 100644 --- a/Autodesk.PackageBuilder/Model/Addin/AddInModel.cs +++ b/Autodesk.PackageBuilder/Model/Addin/AddInModel.cs @@ -2,7 +2,7 @@ { using System.Xml; using System.Xml.Serialization; - public class AddInModel + public class AddInModel : ModelBase { [XmlAttribute] public string Type { get; set; } diff --git a/Autodesk.PackageBuilder/Model/Addin/RevitAddIns.cs b/Autodesk.PackageBuilder/Model/Addin/RevitAddIns.cs index 1118023..39e1185 100644 --- a/Autodesk.PackageBuilder/Model/Addin/RevitAddIns.cs +++ b/Autodesk.PackageBuilder/Model/Addin/RevitAddIns.cs @@ -5,7 +5,7 @@ using System.Xml; using System.Xml.Serialization; [Serializable] - public class RevitAddIns : IPackageSerializable + public class RevitAddIns : ModelBase, IPackageSerializable { [XmlElement] public List AddIn { get; set; } = new List(); diff --git a/Autodesk.PackageBuilder/Model/Application/ApplicationPackage.cs b/Autodesk.PackageBuilder/Model/Application/ApplicationPackage.cs index ad137c9..36dd857 100644 --- a/Autodesk.PackageBuilder/Model/Application/ApplicationPackage.cs +++ b/Autodesk.PackageBuilder/Model/Application/ApplicationPackage.cs @@ -5,7 +5,7 @@ using System.Xml; using System.Xml.Serialization; [Serializable] - public class ApplicationPackage : IPackageSerializable + public class ApplicationPackage : ModelBase, IPackageSerializable { [XmlAttribute] public string SchemaVersion { get; set; } diff --git a/Autodesk.PackageBuilder/Model/Application/CompanyDetails.cs b/Autodesk.PackageBuilder/Model/Application/CompanyDetails.cs index 7c97a9f..316a66b 100644 --- a/Autodesk.PackageBuilder/Model/Application/CompanyDetails.cs +++ b/Autodesk.PackageBuilder/Model/Application/CompanyDetails.cs @@ -2,7 +2,7 @@ { using System.Xml; using System.Xml.Serialization; - public class CompanyDetails + public class CompanyDetails : ModelBase { public CompanyDetails() { } public CompanyDetails(string name, string url, string email = null) diff --git a/Autodesk.PackageBuilder/Model/Application/ComponentEntry.cs b/Autodesk.PackageBuilder/Model/Application/ComponentEntry.cs index f19889c..0af6b35 100644 --- a/Autodesk.PackageBuilder/Model/Application/ComponentEntry.cs +++ b/Autodesk.PackageBuilder/Model/Application/ComponentEntry.cs @@ -2,7 +2,7 @@ { using System.Xml; using System.Xml.Serialization; - public class ComponentEntry + public class ComponentEntry : ModelBase { public ComponentEntry() { } public ComponentEntry(string appName, string moduleName, string version = null, string appDescription = null) diff --git a/Autodesk.PackageBuilder/Model/Application/Components.cs b/Autodesk.PackageBuilder/Model/Application/Components.cs index 4dfccbe..aab6d76 100644 --- a/Autodesk.PackageBuilder/Model/Application/Components.cs +++ b/Autodesk.PackageBuilder/Model/Application/Components.cs @@ -2,7 +2,7 @@ { using System.Xml; using System.Xml.Serialization; - public class Components + public class Components : ModelBase { [XmlAttribute] public string Description { get; set; } diff --git a/Autodesk.PackageBuilder/Model/Application/RuntimeRequirements.cs b/Autodesk.PackageBuilder/Model/Application/RuntimeRequirements.cs index 508b862..eaa1c6f 100644 --- a/Autodesk.PackageBuilder/Model/Application/RuntimeRequirements.cs +++ b/Autodesk.PackageBuilder/Model/Application/RuntimeRequirements.cs @@ -2,7 +2,7 @@ { using System.Xml; using System.Xml.Serialization; - public class RuntimeRequirements + public class RuntimeRequirements : ModelBase { public RuntimeRequirements() { diff --git a/Autodesk.PackageBuilder/Model/ModelBase.cs b/Autodesk.PackageBuilder/Model/ModelBase.cs new file mode 100644 index 0000000..c0d26f9 --- /dev/null +++ b/Autodesk.PackageBuilder/Model/ModelBase.cs @@ -0,0 +1,105 @@ +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Xml; +using System.Xml.Schema; +using System.Xml.Serialization; + +namespace Autodesk.PackageBuilder.Model +{ + public class ModelBase : IXmlSerializable + { + internal Dictionary Aux { get; } = new(); + + public XmlSchema GetSchema() => null; + + public void ReadXml(XmlReader reader) => throw new System.NotImplementedException(); + + public void WriteXml(XmlWriter writer) + { + var properties = this.GetType().GetProperties() + .OrderBy(x => x.MetadataToken) + .Where(p => p.GetCustomAttributes(typeof(XmlIgnoreAttribute), true).Length == 0) + .ToList(); + + var propertiesElements = properties + .Where(p => p.GetCustomAttributes(typeof(XmlElementAttribute), true).Length > 0) + .ToList(); + + var propertiesAttributes = properties + .Where(p => p.GetCustomAttributes(typeof(XmlElementAttribute), true).Length == 0) + .ToList(); + + foreach (var p in propertiesAttributes) + { + var attributeName = p.GetCustomAttribute()?.AttributeName; + var name = string.IsNullOrWhiteSpace(attributeName) ? p.Name : attributeName; + + var value = p.GetValue(this); + if (value != null) + { + writer.WriteAttributeString(name, value.ToString()); + } + } + + foreach (var kvp in Aux) + { + if (!kvp.Value.IsElement) + { + writer.WriteAttributeString(kvp.Key, kvp.Value.Value.ToString()); + } + } + + var namespaces = new XmlSerializerNamespaces(); + namespaces.Add(string.Empty, string.Empty); + + foreach (var p in propertiesElements) + { + var value = p.GetValue(this); + if (value != null) + { + var elementName = p.GetCustomAttribute()?.ElementName; + var name = string.IsNullOrWhiteSpace(elementName) ? p.Name : elementName; + if (value is IEnumerable collection && value is not string) + { + + foreach (var item in collection) + { + var itemSerializer = new XmlSerializer(item.GetType(), new XmlRootAttribute(name)); + itemSerializer.Serialize(writer, item, namespaces); + } + continue; + } + + var elementSerializer = new XmlSerializer(value.GetType(), new XmlRootAttribute(name)); + elementSerializer.Serialize(writer, value, namespaces); + } + } + + foreach (var kvp in Aux) + { + if (kvp.Value.IsElement) + { + var value = kvp.Value.Value; + if (value != null) + { + var elementName = value.GetType().GetCustomAttribute()?.ElementName; + var name = string.IsNullOrWhiteSpace(elementName) ? kvp.Key : elementName; + if (value is IEnumerable collection && value is not string) + { + foreach (var item in collection) + { + var itemSerializer = new XmlSerializer(item.GetType(), new XmlRootAttribute(name)); + itemSerializer.Serialize(writer, item, namespaces); + } + continue; + } + var elementSerializer = new XmlSerializer(value.GetType(), new XmlRootAttribute(name)); + elementSerializer.Serialize(writer, value, namespaces); + } + } + } + } + } +} \ No newline at end of file diff --git a/Autodesk.PackageBuilder/Model/ModelBaseExtension.cs b/Autodesk.PackageBuilder/Model/ModelBaseExtension.cs new file mode 100644 index 0000000..f177855 --- /dev/null +++ b/Autodesk.PackageBuilder/Model/ModelBaseExtension.cs @@ -0,0 +1,25 @@ +namespace Autodesk.PackageBuilder.Model +{ + public static class ModelBaseExtension + { + public static T CreateAttribute(this T model, string name, object value) + where T : ModelBase + { + model.Aux.Add(name, (value, false)); + return model; + } + + public static ModelBase CreateEntryElement(this T model, string name) + where T : ModelBase + { + return model.CreateEntryElement(name, new ModelBase()); + } + + public static TElement CreateEntryElement(this T model, string name, TElement value) + where T : ModelBase + { + model.Aux.Add(name, (value, true)); + return value; + } + } +} \ No newline at end of file diff --git a/Build/Build.csproj b/Build/Build.csproj index dba3b7f..595a26b 100644 --- a/Build/Build.csproj +++ b/Build/Build.csproj @@ -1,7 +1,7 @@  Exe - net6.0 + net8.0 CS0649;CS0169 . diff --git a/CHANGELOG.md b/CHANGELOG.md index 072e7d3..7ddc29a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +## [1.1.0] / 2025-05-16 +### Features +- Support custom `Element` and `Attribute`. +### PackageBuilder +- Add `ModelBase` with custom `IXmlSerializable`. +- Add `ModelBaseExtension` with `CreateEntryElement` and `CreateAttribute`. + ## [1.0.6] / 2023-11-24 - 2023-12-06 ### Features - `Tests` project. @@ -56,6 +63,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - First Release [vNext]: ../../compare/1.0.0...HEAD +[1.1.0]: ../../compare/1.0.6...1.1.0 [1.0.6]: ../../compare/1.0.5...1.0.6 [1.0.5]: ../../compare/1.0.4...1.0.5 [1.0.4]: ../../compare/1.0.3...1.0.4 diff --git a/Directory.Build.props b/Directory.Build.props new file mode 100644 index 0000000..ce2e08d --- /dev/null +++ b/Directory.Build.props @@ -0,0 +1,5 @@ + + + 1.1.0-alpha + + \ No newline at end of file From 9712370818786f24f7da699fbd776857c817d087 Mon Sep 17 00:00:00 2001 From: Luiz Henrique Cassettari Date: Fri, 16 May 2025 16:37:35 -0300 Subject: [PATCH 02/38] Add `DataBase` and `DataBuilderBase` --- .../Builder/Abstractions/BuilderBase.cs | 7 +- .../Abstractions/BuilderBaseExtension.cs | 67 ++++++++++ .../Builder/Abstractions/DataBuilderBase.cs | 51 +++++++ .../Builder/Abstractions/ListBuilderBase.cs | 2 +- .../Builder/Abstractions/SingleBuilderBase.cs | 2 +- .../Model/Addin/AddInApplication.cs | 2 +- .../Model/Addin/AddInModel.cs | 2 +- .../Model/Addin/RevitAddIns.cs | 2 +- .../Model/Application/ApplicationPackage.cs | 2 +- .../Model/Application/CompanyDetails.cs | 2 +- .../Model/Application/ComponentEntry.cs | 2 +- .../Model/Application/Components.cs | 2 +- .../Model/Application/RuntimeRequirements.cs | 2 +- .../Model/Data/DataBase.cs | 126 ++++++++++++++++++ .../Model/Data/DataBaseExtension.cs | 48 +++++++ Autodesk.PackageBuilder/Model/ModelBase.cs | 105 --------------- .../Model/ModelBaseExtension.cs | 25 ---- CHANGELOG.md | 5 +- 18 files changed, 310 insertions(+), 144 deletions(-) create mode 100644 Autodesk.PackageBuilder/Builder/Abstractions/BuilderBaseExtension.cs create mode 100644 Autodesk.PackageBuilder/Builder/Abstractions/DataBuilderBase.cs create mode 100644 Autodesk.PackageBuilder/Model/Data/DataBase.cs create mode 100644 Autodesk.PackageBuilder/Model/Data/DataBaseExtension.cs delete mode 100644 Autodesk.PackageBuilder/Model/ModelBase.cs delete mode 100644 Autodesk.PackageBuilder/Model/ModelBaseExtension.cs diff --git a/Autodesk.PackageBuilder/Builder/Abstractions/BuilderBase.cs b/Autodesk.PackageBuilder/Builder/Abstractions/BuilderBase.cs index 02994e0..b2af44d 100644 --- a/Autodesk.PackageBuilder/Builder/Abstractions/BuilderBase.cs +++ b/Autodesk.PackageBuilder/Builder/Abstractions/BuilderBase.cs @@ -9,13 +9,16 @@ /// public abstract class BuilderBase where TBuilder : class - where TData : new() + where TData : DataBase, new() { /// /// Data /// protected TData Data { get; set; } - + /// + /// DataBuilder + /// + public DataBuilderBase DataBuilder => new(Data); /// /// SetNewPropertyValue /// diff --git a/Autodesk.PackageBuilder/Builder/Abstractions/BuilderBaseExtension.cs b/Autodesk.PackageBuilder/Builder/Abstractions/BuilderBaseExtension.cs new file mode 100644 index 0000000..71bacc3 --- /dev/null +++ b/Autodesk.PackageBuilder/Builder/Abstractions/BuilderBaseExtension.cs @@ -0,0 +1,67 @@ +namespace Autodesk.PackageBuilder +{ + /// + /// Provides extension methods for to simplify attribute and element creation. + /// + public static class BuilderBaseExtension + { + /// + /// Creates a data attribute with the specified name and value, and adds it to the builder's data. + /// + /// The type of the builder. + /// The builder type parameter. + /// The data type parameter. + /// The element type parameter (not used in this method). + /// The builder instance. + /// The name of the attribute to create. + /// The value of the attribute. + /// The builder instance for method chaining. + public static T CreateAttribute(this T builder, string name, object value) + where T : BuilderBase + where TBuilder : class + where TData : DataBase, new() + { + builder.DataBuilder.CreateDataAttribute(name, value); + return builder; + } + + /// + /// Creates a data element with the specified name and value, and adds it to the builder's data. + /// + /// The type of the builder. + /// The builder type parameter. + /// The data type parameter. + /// The type of the element to add. + /// The builder instance. + /// The name of the element to create. + /// The element value to add. + /// The builder instance for method chaining. + public static T CreateEntryElement(this T builder, string name, TElement value) + where T : BuilderBase + where TBuilder : class + where TData : DataBase, new() + where TElement : DataBase + { + builder.DataBuilder.CreateDataElement(name, value); + return builder; + } + + /// + /// Creates a data element with the specified name and adds it to the builder's data. + /// + /// The type of the builder. + /// The builder type parameter. + /// The data type parameter. + /// The builder instance. + /// The name of the element to create. + /// The builder instance for method chaining. + public static T CreateEntryElement(this T builder, string name) + where T : BuilderBase + where TBuilder : class + where TData : DataBase, new() + { + builder.DataBuilder.CreateDataElement(name); + return builder; + } + } +} \ No newline at end of file diff --git a/Autodesk.PackageBuilder/Builder/Abstractions/DataBuilderBase.cs b/Autodesk.PackageBuilder/Builder/Abstractions/DataBuilderBase.cs new file mode 100644 index 0000000..927e520 --- /dev/null +++ b/Autodesk.PackageBuilder/Builder/Abstractions/DataBuilderBase.cs @@ -0,0 +1,51 @@ +namespace Autodesk.PackageBuilder +{ + /// + /// Provides a base builder for constructing and manipulating objects. + /// + public class DataBuilderBase : SingleBuilderBase + { + /// + /// Initializes a new instance of the class with the specified model. + /// + /// The instance to wrap and build upon. + public DataBuilderBase(DataBase model) + { + SetDataInternal(model); + } + + /// + /// Creates a new data attribute with the specified name and value in the underlying . + /// + /// The name of the attribute to create. + /// The value of the attribute. + /// The current instance for method chaining. + public DataBuilderBase CreateDataAttribute(string name, object value) + { + Data.CreateAttribute(name, value); + return this; + } + + /// + /// Creates a new data element with the specified name and returns a builder for the new element. + /// + /// The name of the data element to create. + /// A new instance for the created data element. + public DataBuilderBase CreateDataElement(string name) + { + return new DataBuilderBase(Data.CreateEntryElement(name)); + } + + /// + /// Creates a new data element with the specified name and value, and returns a builder for the new element. + /// + /// The type of the data element, which must derive from . + /// The name of the data element to create. + /// The value of the data element. + /// A new instance for the created data element. + public DataBuilderBase CreateDataElement(string name, TElement value) where TElement : DataBase + { + return new DataBuilderBase(Data.CreateEntryElement(name, value)); + } + } +} \ No newline at end of file diff --git a/Autodesk.PackageBuilder/Builder/Abstractions/ListBuilderBase.cs b/Autodesk.PackageBuilder/Builder/Abstractions/ListBuilderBase.cs index 7dc95e9..d69eaea 100644 --- a/Autodesk.PackageBuilder/Builder/Abstractions/ListBuilderBase.cs +++ b/Autodesk.PackageBuilder/Builder/Abstractions/ListBuilderBase.cs @@ -8,7 +8,7 @@ /// public abstract class ListBuilderBase : BuilderBase where TBuilder : class - where TData : new() + where TData : DataBase, new() { private List _entryList; diff --git a/Autodesk.PackageBuilder/Builder/Abstractions/SingleBuilderBase.cs b/Autodesk.PackageBuilder/Builder/Abstractions/SingleBuilderBase.cs index b85d023..65a6f89 100644 --- a/Autodesk.PackageBuilder/Builder/Abstractions/SingleBuilderBase.cs +++ b/Autodesk.PackageBuilder/Builder/Abstractions/SingleBuilderBase.cs @@ -7,7 +7,7 @@ /// public abstract class SingleBuilderBase : BuilderBase where TBuilder : class - where TData : new() + where TData : DataBase, new() { /// /// SetDataInternal diff --git a/Autodesk.PackageBuilder/Model/Addin/AddInApplication.cs b/Autodesk.PackageBuilder/Model/Addin/AddInApplication.cs index 65636dc..d12587f 100644 --- a/Autodesk.PackageBuilder/Model/Addin/AddInApplication.cs +++ b/Autodesk.PackageBuilder/Model/Addin/AddInApplication.cs @@ -2,7 +2,7 @@ { using System.Xml; using System.Xml.Serialization; - public class AddInApplication : ModelBase + public class AddInApplication : DataBase { [XmlAttribute] public string Type { get; set; } diff --git a/Autodesk.PackageBuilder/Model/Addin/AddInModel.cs b/Autodesk.PackageBuilder/Model/Addin/AddInModel.cs index 802b0d3..dba92de 100644 --- a/Autodesk.PackageBuilder/Model/Addin/AddInModel.cs +++ b/Autodesk.PackageBuilder/Model/Addin/AddInModel.cs @@ -2,7 +2,7 @@ { using System.Xml; using System.Xml.Serialization; - public class AddInModel : ModelBase + public class AddInModel : DataBase { [XmlAttribute] public string Type { get; set; } diff --git a/Autodesk.PackageBuilder/Model/Addin/RevitAddIns.cs b/Autodesk.PackageBuilder/Model/Addin/RevitAddIns.cs index 39e1185..910ed38 100644 --- a/Autodesk.PackageBuilder/Model/Addin/RevitAddIns.cs +++ b/Autodesk.PackageBuilder/Model/Addin/RevitAddIns.cs @@ -5,7 +5,7 @@ using System.Xml; using System.Xml.Serialization; [Serializable] - public class RevitAddIns : ModelBase, IPackageSerializable + public class RevitAddIns : DataBase, IPackageSerializable { [XmlElement] public List AddIn { get; set; } = new List(); diff --git a/Autodesk.PackageBuilder/Model/Application/ApplicationPackage.cs b/Autodesk.PackageBuilder/Model/Application/ApplicationPackage.cs index 36dd857..1adc5c4 100644 --- a/Autodesk.PackageBuilder/Model/Application/ApplicationPackage.cs +++ b/Autodesk.PackageBuilder/Model/Application/ApplicationPackage.cs @@ -5,7 +5,7 @@ using System.Xml; using System.Xml.Serialization; [Serializable] - public class ApplicationPackage : ModelBase, IPackageSerializable + public class ApplicationPackage : DataBase, IPackageSerializable { [XmlAttribute] public string SchemaVersion { get; set; } diff --git a/Autodesk.PackageBuilder/Model/Application/CompanyDetails.cs b/Autodesk.PackageBuilder/Model/Application/CompanyDetails.cs index 316a66b..b12ded8 100644 --- a/Autodesk.PackageBuilder/Model/Application/CompanyDetails.cs +++ b/Autodesk.PackageBuilder/Model/Application/CompanyDetails.cs @@ -2,7 +2,7 @@ { using System.Xml; using System.Xml.Serialization; - public class CompanyDetails : ModelBase + public class CompanyDetails : DataBase { public CompanyDetails() { } public CompanyDetails(string name, string url, string email = null) diff --git a/Autodesk.PackageBuilder/Model/Application/ComponentEntry.cs b/Autodesk.PackageBuilder/Model/Application/ComponentEntry.cs index 0af6b35..f16dd1b 100644 --- a/Autodesk.PackageBuilder/Model/Application/ComponentEntry.cs +++ b/Autodesk.PackageBuilder/Model/Application/ComponentEntry.cs @@ -2,7 +2,7 @@ { using System.Xml; using System.Xml.Serialization; - public class ComponentEntry : ModelBase + public class ComponentEntry : DataBase { public ComponentEntry() { } public ComponentEntry(string appName, string moduleName, string version = null, string appDescription = null) diff --git a/Autodesk.PackageBuilder/Model/Application/Components.cs b/Autodesk.PackageBuilder/Model/Application/Components.cs index aab6d76..6b6c36e 100644 --- a/Autodesk.PackageBuilder/Model/Application/Components.cs +++ b/Autodesk.PackageBuilder/Model/Application/Components.cs @@ -2,7 +2,7 @@ { using System.Xml; using System.Xml.Serialization; - public class Components : ModelBase + public class Components : DataBase { [XmlAttribute] public string Description { get; set; } diff --git a/Autodesk.PackageBuilder/Model/Application/RuntimeRequirements.cs b/Autodesk.PackageBuilder/Model/Application/RuntimeRequirements.cs index eaa1c6f..517f19b 100644 --- a/Autodesk.PackageBuilder/Model/Application/RuntimeRequirements.cs +++ b/Autodesk.PackageBuilder/Model/Application/RuntimeRequirements.cs @@ -2,7 +2,7 @@ { using System.Xml; using System.Xml.Serialization; - public class RuntimeRequirements : ModelBase + public class RuntimeRequirements : DataBase { public RuntimeRequirements() { diff --git a/Autodesk.PackageBuilder/Model/Data/DataBase.cs b/Autodesk.PackageBuilder/Model/Data/DataBase.cs new file mode 100644 index 0000000..85cc4f9 --- /dev/null +++ b/Autodesk.PackageBuilder/Model/Data/DataBase.cs @@ -0,0 +1,126 @@ +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Xml; +using System.Xml.Schema; +using System.Xml.Serialization; + +namespace Autodesk.PackageBuilder; +/// +/// Represents a base class for XML-serializable data models, supporting dynamic attributes and elements. +/// +public class DataBase : IXmlSerializable +{ + /// + /// Gets the auxiliary dictionary for storing additional attributes and elements. + /// The key is the name, and the value is a tuple containing the value and a flag indicating if it is an element. + /// + internal Dictionary Aux { get; } = new(); + + /// + /// This method is reserved and should not be used. When implementing the IXmlSerializable interface, you should return null from this method. + /// + /// Always returns null. + public XmlSchema GetSchema() => null; + + /// + /// Reads the XML representation of the object. Not implemented. + /// + /// The stream from which the object is deserialized. + /// Always thrown. + public void ReadXml(XmlReader reader) => throw new System.NotImplementedException(); + + /// + /// Writes the XML representation of the object, including properties and auxiliary attributes/elements. + /// + /// The stream to which the object is serialized. + public void WriteXml(XmlWriter writer) + { + var properties = this.GetType().GetProperties() + .OrderBy(x => x.MetadataToken) + .Where(p => p.GetCustomAttributes(typeof(XmlIgnoreAttribute), true).Length == 0) + .ToList(); + + var propertiesElements = properties + .Where(p => p.GetCustomAttributes(typeof(XmlElementAttribute), true).Length > 0) + .ToList(); + + var propertiesAttributes = properties + .Where(p => p.GetCustomAttributes(typeof(XmlElementAttribute), true).Length == 0) + .ToList(); + + // Write property attributes as XML attributes + foreach (var p in propertiesAttributes) + { + var attributeName = p.GetCustomAttribute()?.AttributeName; + var name = string.IsNullOrWhiteSpace(attributeName) ? p.Name : attributeName; + + var value = p.GetValue(this); + if (value != null) + { + writer.WriteAttributeString(name, value.ToString()); + } + } + + // Write auxiliary attributes + foreach (var kvp in Aux) + { + if (!kvp.Value.IsElement) + { + writer.WriteAttributeString(kvp.Key, kvp.Value.Value.ToString()); + } + } + + var namespaces = new XmlSerializerNamespaces(); + namespaces.Add(string.Empty, string.Empty); + + // Write property elements as XML elements + foreach (var p in propertiesElements) + { + var value = p.GetValue(this); + if (value != null) + { + var elementName = p.GetCustomAttribute()?.ElementName; + var name = string.IsNullOrWhiteSpace(elementName) ? p.Name : elementName; + if (value is IEnumerable collection && value is not string) + { + foreach (var item in collection) + { + var itemSerializer = new XmlSerializer(item.GetType(), new XmlRootAttribute(name)); + itemSerializer.Serialize(writer, item, namespaces); + } + continue; + } + + var elementSerializer = new XmlSerializer(value.GetType(), new XmlRootAttribute(name)); + elementSerializer.Serialize(writer, value, namespaces); + } + } + + // Write auxiliary elements + foreach (var kvp in Aux) + { + if (kvp.Value.IsElement) + { + var value = kvp.Value.Value; + if (value != null) + { + var elementName = value.GetType().GetCustomAttribute()?.ElementName; + var name = string.IsNullOrWhiteSpace(elementName) ? kvp.Key : elementName; + if (value is IEnumerable collection && value is not string) + { + foreach (var item in collection) + { + var itemSerializer = new XmlSerializer(item.GetType(), new XmlRootAttribute(name)); + itemSerializer.Serialize(writer, item, namespaces); + } + continue; + } + var elementSerializer = new XmlSerializer(value.GetType(), new XmlRootAttribute(name)); + elementSerializer.Serialize(writer, value, namespaces); + } + } + } + } +} \ No newline at end of file diff --git a/Autodesk.PackageBuilder/Model/Data/DataBaseExtension.cs b/Autodesk.PackageBuilder/Model/Data/DataBaseExtension.cs new file mode 100644 index 0000000..53f0d83 --- /dev/null +++ b/Autodesk.PackageBuilder/Model/Data/DataBaseExtension.cs @@ -0,0 +1,48 @@ +namespace Autodesk.PackageBuilder; + +/// +/// Provides extension methods for the class to add dynamic attributes and elements. +/// +public static class DataBaseExtension +{ + /// + /// Adds an attribute to the model. + /// + /// A type derived from . + /// The model to which the attribute will be added. + /// The name of the attribute. + /// The value of the attribute. + /// The modified model instance. + public static T CreateAttribute(this T model, string name, object value) where T : DataBase + { + model.Aux.Add(name, (value, false)); + return model; + } + + /// + /// Adds a new entry element with the specified name to the model. + /// + /// A type derived from . + /// The model to which the entry element will be added. + /// The name of the entry element. + /// The newly created entry element. + public static DataBase CreateEntryElement(this T model, string name) where T : DataBase + { + return model.CreateEntryElement(name, new DataBase()); + } + + /// + /// Adds a new entry element with the specified name and value to the model. + /// + /// A type derived from . + /// The type of the entry element value. + /// The model to which the entry element will be added. + /// The name of the entry element. + /// The value of the entry element. + /// The entry element value. + public static TElement CreateEntryElement(this T model, string name, TElement value) where T : DataBase + { + model.Aux.Add(name, (value, true)); + return value; + } +} diff --git a/Autodesk.PackageBuilder/Model/ModelBase.cs b/Autodesk.PackageBuilder/Model/ModelBase.cs deleted file mode 100644 index c0d26f9..0000000 --- a/Autodesk.PackageBuilder/Model/ModelBase.cs +++ /dev/null @@ -1,105 +0,0 @@ -using System.Collections; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using System.Xml; -using System.Xml.Schema; -using System.Xml.Serialization; - -namespace Autodesk.PackageBuilder.Model -{ - public class ModelBase : IXmlSerializable - { - internal Dictionary Aux { get; } = new(); - - public XmlSchema GetSchema() => null; - - public void ReadXml(XmlReader reader) => throw new System.NotImplementedException(); - - public void WriteXml(XmlWriter writer) - { - var properties = this.GetType().GetProperties() - .OrderBy(x => x.MetadataToken) - .Where(p => p.GetCustomAttributes(typeof(XmlIgnoreAttribute), true).Length == 0) - .ToList(); - - var propertiesElements = properties - .Where(p => p.GetCustomAttributes(typeof(XmlElementAttribute), true).Length > 0) - .ToList(); - - var propertiesAttributes = properties - .Where(p => p.GetCustomAttributes(typeof(XmlElementAttribute), true).Length == 0) - .ToList(); - - foreach (var p in propertiesAttributes) - { - var attributeName = p.GetCustomAttribute()?.AttributeName; - var name = string.IsNullOrWhiteSpace(attributeName) ? p.Name : attributeName; - - var value = p.GetValue(this); - if (value != null) - { - writer.WriteAttributeString(name, value.ToString()); - } - } - - foreach (var kvp in Aux) - { - if (!kvp.Value.IsElement) - { - writer.WriteAttributeString(kvp.Key, kvp.Value.Value.ToString()); - } - } - - var namespaces = new XmlSerializerNamespaces(); - namespaces.Add(string.Empty, string.Empty); - - foreach (var p in propertiesElements) - { - var value = p.GetValue(this); - if (value != null) - { - var elementName = p.GetCustomAttribute()?.ElementName; - var name = string.IsNullOrWhiteSpace(elementName) ? p.Name : elementName; - if (value is IEnumerable collection && value is not string) - { - - foreach (var item in collection) - { - var itemSerializer = new XmlSerializer(item.GetType(), new XmlRootAttribute(name)); - itemSerializer.Serialize(writer, item, namespaces); - } - continue; - } - - var elementSerializer = new XmlSerializer(value.GetType(), new XmlRootAttribute(name)); - elementSerializer.Serialize(writer, value, namespaces); - } - } - - foreach (var kvp in Aux) - { - if (kvp.Value.IsElement) - { - var value = kvp.Value.Value; - if (value != null) - { - var elementName = value.GetType().GetCustomAttribute()?.ElementName; - var name = string.IsNullOrWhiteSpace(elementName) ? kvp.Key : elementName; - if (value is IEnumerable collection && value is not string) - { - foreach (var item in collection) - { - var itemSerializer = new XmlSerializer(item.GetType(), new XmlRootAttribute(name)); - itemSerializer.Serialize(writer, item, namespaces); - } - continue; - } - var elementSerializer = new XmlSerializer(value.GetType(), new XmlRootAttribute(name)); - elementSerializer.Serialize(writer, value, namespaces); - } - } - } - } - } -} \ No newline at end of file diff --git a/Autodesk.PackageBuilder/Model/ModelBaseExtension.cs b/Autodesk.PackageBuilder/Model/ModelBaseExtension.cs deleted file mode 100644 index f177855..0000000 --- a/Autodesk.PackageBuilder/Model/ModelBaseExtension.cs +++ /dev/null @@ -1,25 +0,0 @@ -namespace Autodesk.PackageBuilder.Model -{ - public static class ModelBaseExtension - { - public static T CreateAttribute(this T model, string name, object value) - where T : ModelBase - { - model.Aux.Add(name, (value, false)); - return model; - } - - public static ModelBase CreateEntryElement(this T model, string name) - where T : ModelBase - { - return model.CreateEntryElement(name, new ModelBase()); - } - - public static TElement CreateEntryElement(this T model, string name, TElement value) - where T : ModelBase - { - model.Aux.Add(name, (value, true)); - return value; - } - } -} \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 7ddc29a..fda5c82 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,8 +8,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ### Features - Support custom `Element` and `Attribute`. ### PackageBuilder -- Add `ModelBase` with custom `IXmlSerializable`. -- Add `ModelBaseExtension` with `CreateEntryElement` and `CreateAttribute`. +- Add `DataBase` with custom `IXmlSerializable`. +- Add `DataBaseExtension` with `CreateEntryElement` and `CreateAttribute`. +- Add `DataBuilderBase` and `DataBuilderBaseExtension`. ## [1.0.6] / 2023-11-24 - 2023-12-06 ### Features From c88ca4c685ace78c3110a714adfe90bf0464e143 Mon Sep 17 00:00:00 2001 From: Luiz Henrique Cassettari Date: Fri, 16 May 2025 18:19:39 -0300 Subject: [PATCH 03/38] Add `DataBuild_Tests` to test `DataBuilder` --- .../Data/DataBuild_Tests.cs | 61 ++++++++++++++++ .../Builder/Abstractions/BuilderBase.cs | 35 +++++----- .../Abstractions/BuilderBaseExtension.cs | 67 ------------------ .../Builder/Abstractions/DataBuilderBase.cs | 70 ++++++++++++++++--- .../Model/Data/DataBase.cs | 6 +- .../Model/Data/DataBaseExtension.cs | 12 ++-- CHANGELOG.md | 2 + 7 files changed, 152 insertions(+), 101 deletions(-) create mode 100644 Autodesk.PackageBuilder.Tests/Data/DataBuild_Tests.cs delete mode 100644 Autodesk.PackageBuilder/Builder/Abstractions/BuilderBaseExtension.cs diff --git a/Autodesk.PackageBuilder.Tests/Data/DataBuild_Tests.cs b/Autodesk.PackageBuilder.Tests/Data/DataBuild_Tests.cs new file mode 100644 index 0000000..1669c48 --- /dev/null +++ b/Autodesk.PackageBuilder.Tests/Data/DataBuild_Tests.cs @@ -0,0 +1,61 @@ +using Autodesk.PackageBuilder.Model.Application; +using Autodesk.PackageBuilder.Tests.Utils; +using NUnit.Framework; + +namespace Autodesk.PackageBuilder.Tests.Data +{ + public class DataBuild_Tests + { + PackageContentsBuilder builder; + [SetUp] + public void Setup() + { + builder = BuilderUtils.Build(); + } + + [TestCase("Test", "Test")] + [TestCase("Name", "Value")] + public void DataBuilder_CreateAttribute(string name, object value) + { + var applicationPackageBuilder = builder.ApplicationPackage.Create(); + applicationPackageBuilder.DataBuilder.CreateAttribute(name, value); + + System.Console.WriteLine(builder.ToString()); + + builder.AssertAttribute(name, value); + } + + [TestCase("Test", "Test")] + [TestCase("Name", "Value")] + public void DataBuilder_CreateElement(string name, object value) + { + var applicationPackageBuilder = builder.ApplicationPackage.Create(); + applicationPackageBuilder.DataBuilder.CreateElement(name, value); + + System.Console.WriteLine(builder.ToString()); + + builder.AssertElement(name, value); + } + + [TestCase(3)] + [TestCase(5)] + public void Build_CreateComponentEntry(int length) + { + for (int i = 0; i < length; i++) + { + var componentsBuilder = builder.Components.CreateEntry($"Description {i}"); + + componentsBuilder.DataBuilder.CreateElement("Element", i); + componentsBuilder.DataBuilder.CreateAttribute("Attribute", i); + + } + System.Console.WriteLine(builder.ToString()); + + for (int i = 0; i < length; i++) + { + builder.AssertElement("Element", i); + builder.AssertElementAttribute("ComponentEntry", "Attribute", i); + } + } + } +} \ No newline at end of file diff --git a/Autodesk.PackageBuilder/Builder/Abstractions/BuilderBase.cs b/Autodesk.PackageBuilder/Builder/Abstractions/BuilderBase.cs index b2af44d..f30a1ab 100644 --- a/Autodesk.PackageBuilder/Builder/Abstractions/BuilderBase.cs +++ b/Autodesk.PackageBuilder/Builder/Abstractions/BuilderBase.cs @@ -1,6 +1,7 @@ namespace Autodesk.PackageBuilder { using System; + using System.Linq; using System.Runtime.CompilerServices; /// /// BuilderBase @@ -24,43 +25,45 @@ public abstract class BuilderBase /// /// /// - /// + /// /// - protected TBuilder SetNewPropertyValue(object value, [CallerMemberName] string name = null) where T : new() + protected TBuilder SetNewPropertyValue(object value, [CallerMemberName] string propertyName = null) where T : new() { - return SetNewPropertyValue(Data, name, value); + return SetNewPropertyValue(Data, propertyName, value); } - private TBuilder SetNewPropertyValue(object instance, string method, object value) where T : new() + internal T GetNewPropertyValue(object instance) where T : new() { - var data = new T(); - var name = data.GetType().Name; - var type = instance.GetType(); - var property = type.GetProperty(name) ?? + var property = type.GetProperties().FirstOrDefault(e=>e.PropertyType == typeof(T)) ?? throw new NullReferenceException( - $"Property '{name}' in class {type.Name} not found"); + $"Property with type '{typeof(T)}' in class {type.Name} not found"); if (property.GetValue(instance) == null) - property.SetValue(instance, data); + property.SetValue(instance, new T()); + + return (T)property.GetValue(instance); + } - return SetPropertyValue(property.GetValue(instance), method, value); + private TBuilder SetNewPropertyValue(object instance, string propertyName, object value) where T : new() + { + var data = GetNewPropertyValue(instance); + return SetPropertyValue(data, propertyName, value); } /// /// SetPropertyValue /// /// - /// + /// /// - protected TBuilder SetPropertyValue(object value, [CallerMemberName] string name = null) + protected TBuilder SetPropertyValue(object value, [CallerMemberName] string propertyName = null) { - return SetPropertyValue(Data, name, value); + return SetPropertyValue(Data, propertyName, value); } - private TBuilder SetPropertyValue(object instance, string method, object value) + private TBuilder SetPropertyValue(object instance, string propertyName, object value) { - var propertyName = method; var type = instance.GetType(); var property = type.GetProperty(propertyName) ?? throw new NullReferenceException( diff --git a/Autodesk.PackageBuilder/Builder/Abstractions/BuilderBaseExtension.cs b/Autodesk.PackageBuilder/Builder/Abstractions/BuilderBaseExtension.cs deleted file mode 100644 index 71bacc3..0000000 --- a/Autodesk.PackageBuilder/Builder/Abstractions/BuilderBaseExtension.cs +++ /dev/null @@ -1,67 +0,0 @@ -namespace Autodesk.PackageBuilder -{ - /// - /// Provides extension methods for to simplify attribute and element creation. - /// - public static class BuilderBaseExtension - { - /// - /// Creates a data attribute with the specified name and value, and adds it to the builder's data. - /// - /// The type of the builder. - /// The builder type parameter. - /// The data type parameter. - /// The element type parameter (not used in this method). - /// The builder instance. - /// The name of the attribute to create. - /// The value of the attribute. - /// The builder instance for method chaining. - public static T CreateAttribute(this T builder, string name, object value) - where T : BuilderBase - where TBuilder : class - where TData : DataBase, new() - { - builder.DataBuilder.CreateDataAttribute(name, value); - return builder; - } - - /// - /// Creates a data element with the specified name and value, and adds it to the builder's data. - /// - /// The type of the builder. - /// The builder type parameter. - /// The data type parameter. - /// The type of the element to add. - /// The builder instance. - /// The name of the element to create. - /// The element value to add. - /// The builder instance for method chaining. - public static T CreateEntryElement(this T builder, string name, TElement value) - where T : BuilderBase - where TBuilder : class - where TData : DataBase, new() - where TElement : DataBase - { - builder.DataBuilder.CreateDataElement(name, value); - return builder; - } - - /// - /// Creates a data element with the specified name and adds it to the builder's data. - /// - /// The type of the builder. - /// The builder type parameter. - /// The data type parameter. - /// The builder instance. - /// The name of the element to create. - /// The builder instance for method chaining. - public static T CreateEntryElement(this T builder, string name) - where T : BuilderBase - where TBuilder : class - where TData : DataBase, new() - { - builder.DataBuilder.CreateDataElement(name); - return builder; - } - } -} \ No newline at end of file diff --git a/Autodesk.PackageBuilder/Builder/Abstractions/DataBuilderBase.cs b/Autodesk.PackageBuilder/Builder/Abstractions/DataBuilderBase.cs index 927e520..c447f25 100644 --- a/Autodesk.PackageBuilder/Builder/Abstractions/DataBuilderBase.cs +++ b/Autodesk.PackageBuilder/Builder/Abstractions/DataBuilderBase.cs @@ -20,9 +20,9 @@ public DataBuilderBase(DataBase model) /// The name of the attribute to create. /// The value of the attribute. /// The current instance for method chaining. - public DataBuilderBase CreateDataAttribute(string name, object value) + public DataBuilderBase CreateAttribute(string name, object value) { - Data.CreateAttribute(name, value); + Data.CreateDataAttribute(name, value); return this; } @@ -31,21 +31,73 @@ public DataBuilderBase CreateDataAttribute(string name, object value) /// /// The name of the data element to create. /// A new instance for the created data element. - public DataBuilderBase CreateDataElement(string name) + public DataBuilderBase CreateElement(string name) { - return new DataBuilderBase(Data.CreateEntryElement(name)); + return new DataBuilderBase(Data.CreateDataElement(name)); } /// - /// Creates a new data element with the specified name and value, and returns a builder for the new element. + /// Creates a new data element with the specified name and value in the underlying . /// - /// The type of the data element, which must derive from . + /// The type of the value to associate with the new data element. + /// The name of the data element to create. + /// The value to associate with the new data element. If the value is a , it will be used to create a nested element. + /// + /// A new instance for the created data element if is a ; otherwise, null. + /// + public DataBuilderBase CreateElement(string name, object value) + { + if (value is DataBase dataBase) + return new DataBuilderBase(Data.CreateDataElement(name, dataBase)); + + Data.CreateDataElement(name, value); + return null; + } + + /// + /// Creates a new data attribute with the specified name and value in a new instance of derived from . + /// + /// The type of to use for creating the attribute. Must have a parameterless constructor. + /// The name of the attribute to create. + /// The value of the attribute. + /// The current instance for method chaining. + public DataBuilderBase CreateAttribute(string name, object value) where T : DataBase, new() + { + var data = GetNewPropertyValue(Data); + data.CreateDataAttribute(name, value); + return this; + } + + /// + /// Creates a new data element with the specified name in a new instance of derived from . + /// + /// The type of to use for creating the element. Must have a parameterless constructor. /// The name of the data element to create. - /// The value of the data element. /// A new instance for the created data element. - public DataBuilderBase CreateDataElement(string name, TElement value) where TElement : DataBase + public DataBuilderBase CreateElement(string name) where T : DataBase, new() + { + var data = GetNewPropertyValue(Data); + return new DataBuilderBase(data.CreateDataElement(name)); + } + + /// + /// Creates a new data element with the specified name and value in a new instance of derived from . + /// + /// The type of to use for creating the element. Must have a parameterless constructor. + /// The name of the data element to create. + /// The value to associate with the new data element. If the value is a , it will be used to create a nested element. + /// + /// A new instance for the created data element if is a ; otherwise, null. + /// + public DataBuilderBase CreateElement(string name, object value) where T : DataBase, new() { - return new DataBuilderBase(Data.CreateEntryElement(name, value)); + var data = GetNewPropertyValue(Data); + + if (value is DataBase dataBase) + return new DataBuilderBase(data.CreateDataElement(name, dataBase)); + + data.CreateDataElement(name, value); + return null; } } } \ No newline at end of file diff --git a/Autodesk.PackageBuilder/Model/Data/DataBase.cs b/Autodesk.PackageBuilder/Model/Data/DataBase.cs index 85cc4f9..18a20d8 100644 --- a/Autodesk.PackageBuilder/Model/Data/DataBase.cs +++ b/Autodesk.PackageBuilder/Model/Data/DataBase.cs @@ -16,7 +16,7 @@ public class DataBase : IXmlSerializable /// Gets the auxiliary dictionary for storing additional attributes and elements. /// The key is the name, and the value is a tuple containing the value and a flag indicating if it is an element. /// - internal Dictionary Aux { get; } = new(); + internal Dictionary Auxiliary { get; } = new(); /// /// This method is reserved and should not be used. When implementing the IXmlSerializable interface, you should return null from this method. @@ -64,7 +64,7 @@ public void WriteXml(XmlWriter writer) } // Write auxiliary attributes - foreach (var kvp in Aux) + foreach (var kvp in Auxiliary) { if (!kvp.Value.IsElement) { @@ -99,7 +99,7 @@ public void WriteXml(XmlWriter writer) } // Write auxiliary elements - foreach (var kvp in Aux) + foreach (var kvp in Auxiliary) { if (kvp.Value.IsElement) { diff --git a/Autodesk.PackageBuilder/Model/Data/DataBaseExtension.cs b/Autodesk.PackageBuilder/Model/Data/DataBaseExtension.cs index 53f0d83..5931848 100644 --- a/Autodesk.PackageBuilder/Model/Data/DataBaseExtension.cs +++ b/Autodesk.PackageBuilder/Model/Data/DataBaseExtension.cs @@ -13,9 +13,9 @@ public static class DataBaseExtension /// The name of the attribute. /// The value of the attribute. /// The modified model instance. - public static T CreateAttribute(this T model, string name, object value) where T : DataBase + public static T CreateDataAttribute(this T model, string name, object value) where T : DataBase { - model.Aux.Add(name, (value, false)); + model.Auxiliary.Add(name, (value, false)); return model; } @@ -26,9 +26,9 @@ public static T CreateAttribute(this T model, string name, object value) wher /// The model to which the entry element will be added. /// The name of the entry element. /// The newly created entry element. - public static DataBase CreateEntryElement(this T model, string name) where T : DataBase + public static DataBase CreateDataElement(this T model, string name) where T : DataBase { - return model.CreateEntryElement(name, new DataBase()); + return model.CreateDataElement(name, new DataBase()); } /// @@ -40,9 +40,9 @@ public static DataBase CreateEntryElement(this T model, string name) where T /// The name of the entry element. /// The value of the entry element. /// The entry element value. - public static TElement CreateEntryElement(this T model, string name, TElement value) where T : DataBase + public static TElement CreateDataElement(this T model, string name, TElement value) where T : DataBase { - model.Aux.Add(name, (value, true)); + model.Auxiliary.Add(name, (value, true)); return value; } } diff --git a/CHANGELOG.md b/CHANGELOG.md index fda5c82..791197a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Add `DataBase` with custom `IXmlSerializable`. - Add `DataBaseExtension` with `CreateEntryElement` and `CreateAttribute`. - Add `DataBuilderBase` and `DataBuilderBaseExtension`. +### Tests +- Add `DataBuild_Tests` to test `DataBuilder` ## [1.0.6] / 2023-11-24 - 2023-12-06 ### Features From 8d215287a236d3ff0404476243a258ba49ec5a90 Mon Sep 17 00:00:00 2001 From: Luiz Henrique Cassettari Date: Fri, 16 May 2025 18:25:29 -0300 Subject: [PATCH 04/38] Update docs --- .../Abstractions/Addin/IAddInEntryBuilder.cs | 10 ++ .../Application/IApplicationPackageBuilder.cs | 8 ++ .../Application/ICompanyDetailsBuilder.cs | 10 ++ .../Application/IComponentsEntryBuilder.cs | 8 ++ .../Builder/Abstractions/DataBuilderBase.cs | 11 +- .../Builder/Addin/AddInEntryBuilder.cs | 60 +++++++++++ .../Builder/Addin/RevitAddInsEntryBuilder.cs | 7 ++ .../Application/ApplicationPackageBuilder.cs | 100 +++++++++++++++++- .../Application/CompanyDetailsBuilder.cs | 29 +++++ .../Builder/Application/ComponentsBuilder.cs | 65 ++++++++++++ .../Builder/PackageContentsBuilder.cs | 26 ++++- .../Builder/RevitAddInsBuilder.cs | 29 ++++- .../Constants/AutodeskProducts.cs | 18 ++++ .../Constants/ProductTypes.cs | 10 ++ .../Model/Addin/AddInApplication.cs | 27 +++++ .../Model/Addin/AddInModel.cs | 24 +++++ .../Model/Addin/RevitAddIns.cs | 6 ++ .../Model/Application/ApplicationPackage.cs | 45 ++++++++ .../Model/Application/CompanyDetails.cs | 23 ++++ .../Model/Application/ComponentEntry.cs | 27 +++++ .../Model/Application/Components.cs | 12 +++ .../Model/Application/RuntimeRequirements.cs | 27 ++++- Autodesk.PackageBuilder/Utils/BuilderUtils.cs | 6 +- 23 files changed, 572 insertions(+), 16 deletions(-) diff --git a/Autodesk.PackageBuilder/Builder/Abstractions/Addin/IAddInEntryBuilder.cs b/Autodesk.PackageBuilder/Builder/Abstractions/Addin/IAddInEntryBuilder.cs index c38a8b1..6bb15c3 100644 --- a/Autodesk.PackageBuilder/Builder/Abstractions/Addin/IAddInEntryBuilder.cs +++ b/Autodesk.PackageBuilder/Builder/Abstractions/Addin/IAddInEntryBuilder.cs @@ -1,7 +1,17 @@ namespace Autodesk.PackageBuilder { + /// + /// Defines a builder interface for creating add-in entry configurations. + /// public interface IAddInEntryBuilder { + /// + /// Creates a new add-in entry with the specified type. + /// + /// The type of the add-in entry. Defaults to "Application". + /// + /// An instance for further configuration of the add-in entry. + /// AddInEntryBuilder CreateEntry(string type = "Application"); } } \ No newline at end of file diff --git a/Autodesk.PackageBuilder/Builder/Abstractions/Application/IApplicationPackageBuilder.cs b/Autodesk.PackageBuilder/Builder/Abstractions/Application/IApplicationPackageBuilder.cs index 08dadeb..821f4bc 100644 --- a/Autodesk.PackageBuilder/Builder/Abstractions/Application/IApplicationPackageBuilder.cs +++ b/Autodesk.PackageBuilder/Builder/Abstractions/Application/IApplicationPackageBuilder.cs @@ -1,7 +1,15 @@ namespace Autodesk.PackageBuilder { + /// + /// Defines a builder interface for creating instances. + /// public interface IApplicationPackageBuilder { + /// + /// Creates a new instance with the specified schema version. + /// + /// The schema version to use for the application package. Defaults to "1.0". + /// An instance initialized with the given schema version. ApplicationPackageBuilder Create(string schemaVersion = "1.0"); } } \ No newline at end of file diff --git a/Autodesk.PackageBuilder/Builder/Abstractions/Application/ICompanyDetailsBuilder.cs b/Autodesk.PackageBuilder/Builder/Abstractions/Application/ICompanyDetailsBuilder.cs index 5fae227..473c84c 100644 --- a/Autodesk.PackageBuilder/Builder/Abstractions/Application/ICompanyDetailsBuilder.cs +++ b/Autodesk.PackageBuilder/Builder/Abstractions/Application/ICompanyDetailsBuilder.cs @@ -1,7 +1,17 @@ namespace Autodesk.PackageBuilder { + /// + /// Defines a builder interface for creating instances. + /// public interface ICompanyDetailsBuilder { + /// + /// Creates a new for the specified company name. + /// + /// The name of the company. + /// + /// A instance initialized with the specified company name. + /// CompanyDetailsBuilder Create(string name); } } \ No newline at end of file diff --git a/Autodesk.PackageBuilder/Builder/Abstractions/Application/IComponentsEntryBuilder.cs b/Autodesk.PackageBuilder/Builder/Abstractions/Application/IComponentsEntryBuilder.cs index a61b02b..ff740cb 100644 --- a/Autodesk.PackageBuilder/Builder/Abstractions/Application/IComponentsEntryBuilder.cs +++ b/Autodesk.PackageBuilder/Builder/Abstractions/Application/IComponentsEntryBuilder.cs @@ -1,7 +1,15 @@ namespace Autodesk.PackageBuilder { + /// + /// Defines a builder interface for creating entries. + /// public interface IComponentsEntryBuilder { + /// + /// Creates a new entry with the specified description. + /// + /// The description for the components entry. + /// A instance for further configuration. ComponentsBuilder CreateEntry(string description); } } \ No newline at end of file diff --git a/Autodesk.PackageBuilder/Builder/Abstractions/DataBuilderBase.cs b/Autodesk.PackageBuilder/Builder/Abstractions/DataBuilderBase.cs index c447f25..0574547 100644 --- a/Autodesk.PackageBuilder/Builder/Abstractions/DataBuilderBase.cs +++ b/Autodesk.PackageBuilder/Builder/Abstractions/DataBuilderBase.cs @@ -3,6 +3,11 @@ /// /// Provides a base builder for constructing and manipulating objects. /// + /// + /// This builder offers a fluent API for creating and modifying attributes and elements + /// within a instance. It supports both direct manipulation of the + /// underlying data model and creation of nested elements or attributes using generic overloads. + /// public class DataBuilderBase : SingleBuilderBase { /// @@ -39,9 +44,11 @@ public DataBuilderBase CreateElement(string name) /// /// Creates a new data element with the specified name and value in the underlying . /// - /// The type of the value to associate with the new data element. /// The name of the data element to create. - /// The value to associate with the new data element. If the value is a , it will be used to create a nested element. + /// + /// The value to associate with the new data element. If the value is a , it will be used to create a nested element. + /// Otherwise, the value will be set directly. + /// /// /// A new instance for the created data element if is a ; otherwise, null. /// diff --git a/Autodesk.PackageBuilder/Builder/Addin/AddInEntryBuilder.cs b/Autodesk.PackageBuilder/Builder/Addin/AddInEntryBuilder.cs index 6aa7f82..2bceabd 100644 --- a/Autodesk.PackageBuilder/Builder/Addin/AddInEntryBuilder.cs +++ b/Autodesk.PackageBuilder/Builder/Addin/AddInEntryBuilder.cs @@ -2,13 +2,25 @@ { using Model.Addin; using System.Collections.Generic; + /// + /// Provides a builder for creating and configuring entries. + /// public class AddInEntryBuilder : ListBuilderBase, IAddInEntryBuilder { + /// + /// Initializes a new instance of the class with the specified list of objects. + /// + /// The list of objects to initialize the builder with. public AddInEntryBuilder(List models) { SetDataInternal(models); } + /// + /// Creates a new add-in entry and sets its type. + /// + /// The type of the add-in entry (e.g., "Application"). + /// The current instance for method chaining. public AddInEntryBuilder CreateEntry(string type) { CreateEntryInternal(); @@ -16,13 +28,61 @@ public AddInEntryBuilder CreateEntry(string type) return this; } + /// + /// Sets the property for the current entry. + /// + /// The type value to set. + /// The current instance for method chaining. private AddInEntryBuilder Type(string value) => SetPropertyValue(value); + + /// + /// Sets the property for the current entry. + /// + /// The name value to set. + /// The current instance for method chaining. public AddInEntryBuilder Name(string value) => SetPropertyValue(value); + + /// + /// Sets the property for the current entry. + /// + /// The assembly value to set. + /// The current instance for method chaining. public AddInEntryBuilder Assembly(string value) => SetPropertyValue(value); + + /// + /// Sets the property for the current entry. + /// + /// The add-in ID value to set. + /// The current instance for method chaining. public AddInEntryBuilder AddInId(string value) => SetPropertyValue(value); + + /// + /// Sets the property for the current entry. + /// + /// The fully qualified class name to set. + /// The current instance for method chaining. public AddInEntryBuilder FullClassName(string value) => SetPropertyValue(value); + + /// + /// Sets the property for the current entry. + /// + /// The vendor ID value to set. + /// The current instance for method chaining. public AddInEntryBuilder VendorId(string value) => SetPropertyValue(value); + + /// + /// Sets the property for the current entry. + /// + /// The vendor description value to set. + /// The current instance for method chaining. public AddInEntryBuilder VendorDescription(string value) => SetPropertyValue(value); + + /// + /// (Obsolete) Sets the AllowLoadingIntoExistingSession property for the current entry. + /// This method is obsolete and will be removed in a future version. + /// + /// A value indicating whether loading into an existing session is allowed. + /// The current instance for method chaining. [System.Obsolete("This method does not have a Property 'AllowLoadingIntoExistingSession' in class AddInModel, will be removed in a future version.")] internal AddInEntryBuilder AllowLoadingIntoExistingSession(bool value) => SetPropertyValue(value); } diff --git a/Autodesk.PackageBuilder/Builder/Addin/RevitAddInsEntryBuilder.cs b/Autodesk.PackageBuilder/Builder/Addin/RevitAddInsEntryBuilder.cs index 73a4c58..aad32a4 100644 --- a/Autodesk.PackageBuilder/Builder/Addin/RevitAddInsEntryBuilder.cs +++ b/Autodesk.PackageBuilder/Builder/Addin/RevitAddInsEntryBuilder.cs @@ -1,8 +1,15 @@ namespace Autodesk.PackageBuilder { using Model.Addin; + /// + /// Provides a builder for entries, enabling fluent construction and configuration of Revit add-in collections. + /// public class RevitAddInsEntryBuilder : SingleBuilderBase { + /// + /// Initializes a new instance of the class with the specified model. + /// + /// The model to initialize the builder with. public RevitAddInsEntryBuilder(RevitAddIns model) { SetDataInternal(model); diff --git a/Autodesk.PackageBuilder/Builder/Application/ApplicationPackageBuilder.cs b/Autodesk.PackageBuilder/Builder/Application/ApplicationPackageBuilder.cs index 566c0b5..5cd3375 100644 --- a/Autodesk.PackageBuilder/Builder/Application/ApplicationPackageBuilder.cs +++ b/Autodesk.PackageBuilder/Builder/Application/ApplicationPackageBuilder.cs @@ -3,30 +3,126 @@ using Model.Application; using System; + /// + /// Provides a builder for constructing instances with a fluent API. + /// public class ApplicationPackageBuilder : SingleBuilderBase, IApplicationPackageBuilder { + /// + /// Initializes a new instance of the class with the specified data. + /// + /// The application package data to initialize the builder with. public ApplicationPackageBuilder(ApplicationPackage applicationPackage) { SetDataInternal(applicationPackage); } - public ApplicationPackageBuilder Create( - string schemaVersion) + + /// + /// Creates a new instance with the specified schema version. + /// + /// The schema version to set for the application package. + /// The instance for chaining. + public ApplicationPackageBuilder Create(string schemaVersion) { return SchemaVersion(schemaVersion); } + + /// + /// Sets the schema version for the application package. + /// + /// The schema version value. + /// The instance for chaining. private ApplicationPackageBuilder SchemaVersion(string value) => SetPropertyValue(value); + + /// + /// Sets the name of the application package. + /// + /// The name value. + /// The instance for chaining. public ApplicationPackageBuilder Name(string value) => SetPropertyValue(value); + + /// + /// Sets the Autodesk product associated with the application package. + /// + /// The Autodesk product value. + /// The instance for chaining. public ApplicationPackageBuilder AutodeskProduct(string value) => SetPropertyValue(value); + + /// + /// Sets the description of the application package. + /// + /// The description value. + /// The instance for chaining. public ApplicationPackageBuilder Description(string value) => SetPropertyValue(value); + + /// + /// Sets the application version as a string. + /// + /// The application version value. + /// The instance for chaining. public ApplicationPackageBuilder AppVersion(string value) => SetPropertyValue(value); + + /// + /// Sets the application version using a object. + /// + /// The application version as a . + /// The instance for chaining. public ApplicationPackageBuilder AppVersion(Version value) => SetPropertyValue(value.ToString()); + + /// + /// Sets the user-friendly version string for the application package. + /// + /// The friendly version value. + /// The instance for chaining. public ApplicationPackageBuilder FriendlyVersion(string value) => SetPropertyValue(value); + + /// + /// Sets the product type of the application package. + /// + /// The product type value. + /// The instance for chaining. public ApplicationPackageBuilder ProductType(string value) => SetPropertyValue(value); + + /// + /// Sets the product code of the application package as a string. + /// + /// The product code value. + /// The instance for chaining. public ApplicationPackageBuilder ProductCode(string value) => SetPropertyValue(value); + + /// + /// Sets the product code of the application package using a . + /// + /// The product code as a . + /// The instance for chaining. public ApplicationPackageBuilder ProductCode(Guid value) => SetPropertyValue(value.ToString()); + + /// + /// Sets the author of the application package. + /// + /// The author value. + /// The instance for chaining. public ApplicationPackageBuilder Author(string value) => SetPropertyValue(value); + + /// + /// Sets the help file associated with the application package. + /// + /// The help file value. + /// The instance for chaining. public ApplicationPackageBuilder HelpFile(string value) => SetPropertyValue(value); + + /// + /// Sets the supported locales for the application package. + /// + /// The supported locales value. + /// The instance for chaining. public ApplicationPackageBuilder SupportedLocales(string value) => SetPropertyValue(value); + + /// + /// Sets the URL to the online documentation for the application package. + /// + /// The online documentation URL. + /// The instance for chaining. public ApplicationPackageBuilder OnlineDocumentation(string value) => SetPropertyValue(value); } diff --git a/Autodesk.PackageBuilder/Builder/Application/CompanyDetailsBuilder.cs b/Autodesk.PackageBuilder/Builder/Application/CompanyDetailsBuilder.cs index 8ef681f..2d03cfa 100644 --- a/Autodesk.PackageBuilder/Builder/Application/CompanyDetailsBuilder.cs +++ b/Autodesk.PackageBuilder/Builder/Application/CompanyDetailsBuilder.cs @@ -1,20 +1,49 @@ namespace Autodesk.PackageBuilder { using Model.Application; + /// + /// Provides a builder for constructing instances. + /// public class CompanyDetailsBuilder : SingleBuilderBase, ICompanyDetailsBuilder { + /// + /// Initializes a new instance of the class with the specified data. + /// + /// The instance to initialize the builder with. public CompanyDetailsBuilder(CompanyDetails companyDetails) { SetDataInternal(companyDetails); } + /// + /// Creates a new and sets the company name. + /// + /// The name of the company. + /// The current instance with the specified name set. public CompanyDetailsBuilder Create(string name) { return Name(name); } + /// + /// Sets the name of the company. + /// + /// The company name. + /// The current instance. private CompanyDetailsBuilder Name(string value) => SetPropertyValue(value); + + /// + /// Sets the URL of the company. + /// + /// The company URL. + /// The current instance. public CompanyDetailsBuilder Url(string value) => SetPropertyValue(value); + + /// + /// Sets the email address of the company. + /// + /// The company email address. + /// The current instance. public CompanyDetailsBuilder Email(string value) => SetPropertyValue(value); } diff --git a/Autodesk.PackageBuilder/Builder/Application/ComponentsBuilder.cs b/Autodesk.PackageBuilder/Builder/Application/ComponentsBuilder.cs index 40489ca..ebd246e 100644 --- a/Autodesk.PackageBuilder/Builder/Application/ComponentsBuilder.cs +++ b/Autodesk.PackageBuilder/Builder/Application/ComponentsBuilder.cs @@ -2,13 +2,25 @@ { using Model.Application; using System.Collections.Generic; + /// + /// Provides a builder for creating and configuring entries. + /// public class ComponentsBuilder : ListBuilderBase, IComponentsEntryBuilder { + /// + /// Initializes a new instance of the class with the specified components list. + /// + /// The list of to initialize the builder with. public ComponentsBuilder(List components) { SetDataInternal(components); } + /// + /// Creates a new entry with the specified description. + /// + /// The description for the components entry. + /// The current instance for further configuration. public ComponentsBuilder CreateEntry(string description) { CreateEntryInternal(); @@ -16,14 +28,67 @@ public ComponentsBuilder CreateEntry(string description) return this; } + /// + /// Sets the description for the current entry. + /// + /// The description value. + /// The current instance. private ComponentsBuilder Description(string value) => SetPropertyValue(value); + + /// + /// Sets the operating system requirement for the current entry. + /// + /// The operating system value. + /// The current instance. public ComponentsBuilder OS(string value) => SetNewPropertyValue(value); + + /// + /// Sets the platform requirement for the current entry. + /// + /// The platform value. + /// The current instance. public ComponentsBuilder Platform(string value) => SetNewPropertyValue(value); + + /// + /// Sets the minimum supported series version for the current entry. + /// + /// The minimum series version value. + /// The current instance. public ComponentsBuilder SeriesMin(string value) => SetNewPropertyValue(value); + + /// + /// Sets the maximum supported series version for the current entry. + /// + /// The maximum series version value. + /// The current instance. public ComponentsBuilder SeriesMax(string value) => SetNewPropertyValue(value); + + /// + /// Sets the application name for the current in the entry. + /// + /// The application name value. + /// The current instance. public ComponentsBuilder AppName(string value) => SetNewPropertyValue(value); + + /// + /// Sets the module name for the current in the entry. + /// + /// The module name value. + /// The current instance. public ComponentsBuilder ModuleName(string value) => SetNewPropertyValue(value); + + /// + /// Sets the version for the current in the entry. + /// + /// The version value. + /// The current instance. public ComponentsBuilder Version(string value) => SetNewPropertyValue(value); + + /// + /// Sets the application description for the current in the entry. + /// + /// The application description value. + /// The current instance. public ComponentsBuilder AppDescription(string value) => SetNewPropertyValue(value); } diff --git a/Autodesk.PackageBuilder/Builder/PackageContentsBuilder.cs b/Autodesk.PackageBuilder/Builder/PackageContentsBuilder.cs index b540322..c8b9cb4 100644 --- a/Autodesk.PackageBuilder/Builder/PackageContentsBuilder.cs +++ b/Autodesk.PackageBuilder/Builder/PackageContentsBuilder.cs @@ -2,6 +2,10 @@ { using Model.Application; + /// + /// Provides a builder for constructing and serializing an Autodesk application package, + /// including application metadata, company details, and components. + /// public class PackageContentsBuilder : IBuilder { private readonly ApplicationPackage applicationPackage; @@ -10,12 +14,24 @@ public class PackageContentsBuilder : IBuilder private readonly CompanyDetailsBuilder _companyDetailsBuilder; private readonly ComponentsBuilder _components; + /// + /// Gets the builder for configuring the application package metadata. + /// public IApplicationPackageBuilder ApplicationPackage => _applicationPackage; + /// + /// Gets the builder for configuring the company details. + /// public ICompanyDetailsBuilder CompanyDetails => _companyDetailsBuilder; + /// + /// Gets the builder for configuring the components entries. + /// public IComponentsEntryBuilder Components => _components; + /// + /// Initializes a new instance of the class. + /// public PackageContentsBuilder() { applicationPackage = new ApplicationPackage(); @@ -25,15 +41,19 @@ public PackageContentsBuilder() } /// - /// Build and serialize the PackageContents.xml file. + /// Builds and serializes the PackageContents.xml file to the specified path. /// - /// - /// + /// The directory path where the XML file will be saved. + /// The full file path of the generated PackageContents.xml file. public string Build(string path) { return applicationPackage.SerializeFile(path, "PackageContents.xml"); } + /// + /// Returns the XML string representation of the application package. + /// + /// A string containing the serialized XML of the application package. public override string ToString() { return applicationPackage.SerializeObject(); diff --git a/Autodesk.PackageBuilder/Builder/RevitAddInsBuilder.cs b/Autodesk.PackageBuilder/Builder/RevitAddInsBuilder.cs index 32a8361..45dc4dc 100644 --- a/Autodesk.PackageBuilder/Builder/RevitAddInsBuilder.cs +++ b/Autodesk.PackageBuilder/Builder/RevitAddInsBuilder.cs @@ -1,15 +1,34 @@ namespace Autodesk.PackageBuilder { using Model.Addin; + /// + /// Provides a builder for creating and serializing Revit add-in configuration files (.addin). + /// public class RevitAddInsBuilder : IBuilder { + /// + /// The instance representing the collection of add-in entries. + /// private readonly RevitAddIns revitAddIns; + /// + /// The builder for configuring the entry. + /// private readonly RevitAddInsEntryBuilder _revitAddInsEntryBuilder; + + /// + /// The builder for configuring individual add-in entries. + /// private readonly AddInEntryBuilder _addInEntryBuilder; + /// + /// Gets the builder for creating and configuring add-in entries. + /// public IAddInEntryBuilder AddIn => _addInEntryBuilder; + /// + /// Initializes a new instance of the class. + /// public RevitAddInsBuilder() { revitAddIns = new RevitAddIns(); @@ -18,19 +37,19 @@ public RevitAddInsBuilder() } /// - /// Build and serialize the .addin file. + /// Builds and serializes the Revit add-in configuration to a .addin file at the specified path. /// - /// - /// + /// The file path where the .addin file will be saved. + /// The full path to the serialized .addin file. public string Build(string path) { return revitAddIns.SerializeFile(path, ".addin"); } /// - /// Serialize the RevitAddIns object. + /// Serializes the object to its XML string representation. /// - /// + /// A string containing the XML representation of the Revit add-ins configuration. public override string ToString() { return revitAddIns.SerializeObject(); diff --git a/Autodesk.PackageBuilder/Constants/AutodeskProducts.cs b/Autodesk.PackageBuilder/Constants/AutodeskProducts.cs index 00f227b..f05066c 100644 --- a/Autodesk.PackageBuilder/Constants/AutodeskProducts.cs +++ b/Autodesk.PackageBuilder/Constants/AutodeskProducts.cs @@ -1,10 +1,28 @@ namespace Autodesk.PackageBuilder { + /// + /// Provides constant product names for supported Autodesk products. + /// public static class AutodeskProducts { + /// + /// The product name for Autodesk Revit. + /// public const string Revit = "Revit"; + + /// + /// The product name for Autodesk AutoCAD. + /// public const string AutoCAD = "AutoCAD"; + + /// + /// The product name for Autodesk Maya. + /// public const string Maya = "Maya"; + + /// + /// The product name for Autodesk Navisworks. + /// public const string Navisworks = "Navisworks"; } diff --git a/Autodesk.PackageBuilder/Constants/ProductTypes.cs b/Autodesk.PackageBuilder/Constants/ProductTypes.cs index a53a2b4..304f7df 100644 --- a/Autodesk.PackageBuilder/Constants/ProductTypes.cs +++ b/Autodesk.PackageBuilder/Constants/ProductTypes.cs @@ -1,8 +1,18 @@ namespace Autodesk.PackageBuilder { + /// + /// Provides constant values for different product types supported by the package builder. + /// public static class ProductTypes { + /// + /// Represents the product type for applications. + /// public const string Application = "Application"; + + /// + /// Represents the product type for content packages. + /// public const string Content = "Content"; } diff --git a/Autodesk.PackageBuilder/Model/Addin/AddInApplication.cs b/Autodesk.PackageBuilder/Model/Addin/AddInApplication.cs index d12587f..8d57680 100644 --- a/Autodesk.PackageBuilder/Model/Addin/AddInApplication.cs +++ b/Autodesk.PackageBuilder/Model/Addin/AddInApplication.cs @@ -2,29 +2,56 @@ { using System.Xml; using System.Xml.Serialization; + /// + /// Represents an add-in application definition for Autodesk products. + /// public class AddInApplication : DataBase { + /// + /// Gets or sets the type of the add-in application. + /// [XmlAttribute] public string Type { get; set; } + /// + /// Gets or sets the display name of the add-in application. + /// [XmlElement] public string Name { get; set; } + /// + /// Gets or sets the assembly file name or path for the add-in application. + /// [XmlElement] public string Assembly { get; set; } + /// + /// Gets or sets the unique identifier for the add-in application. + /// [XmlElement] public string AddInId { get; set; } + /// + /// Gets or sets the fully qualified class name that implements the add-in application. + /// [XmlElement] public string FullClassName { get; set; } + /// + /// Gets or sets the vendor identifier for the add-in application. + /// [XmlElement] public string VendorId { get; set; } + /// + /// Gets or sets the vendor description for the add-in application. + /// [XmlElement] public string VendorDescription { get; set; } + /// + /// Gets or sets a value indicating whether the add-in can be loaded into an existing session. + /// [XmlElement] public bool AllowLoadingIntoExistingSession { get; set; } = true; } diff --git a/Autodesk.PackageBuilder/Model/Addin/AddInModel.cs b/Autodesk.PackageBuilder/Model/Addin/AddInModel.cs index dba92de..93f9a71 100644 --- a/Autodesk.PackageBuilder/Model/Addin/AddInModel.cs +++ b/Autodesk.PackageBuilder/Model/Addin/AddInModel.cs @@ -2,26 +2,50 @@ { using System.Xml; using System.Xml.Serialization; + /// + /// Represents an add-in model for Autodesk Package Builder, containing metadata for an add-in. + /// public class AddInModel : DataBase { + /// + /// Gets or sets the type of the add-in. + /// [XmlAttribute] public string Type { get; set; } + /// + /// Gets or sets the name of the add-in. + /// [XmlElement] public string Name { get; set; } + /// + /// Gets or sets the assembly file name or path for the add-in. + /// [XmlElement] public string Assembly { get; set; } + /// + /// Gets or sets the unique identifier for the add-in. + /// [XmlElement] public string AddInId { get; set; } + /// + /// Gets or sets the fully qualified class name that implements the add-in. + /// [XmlElement] public string FullClassName { get; set; } + /// + /// Gets or sets the vendor identifier for the add-in. + /// [XmlElement] public string VendorId { get; set; } + /// + /// Gets or sets the vendor description for the add-in. + /// [XmlElement] public string VendorDescription { get; set; } } diff --git a/Autodesk.PackageBuilder/Model/Addin/RevitAddIns.cs b/Autodesk.PackageBuilder/Model/Addin/RevitAddIns.cs index 910ed38..017c41a 100644 --- a/Autodesk.PackageBuilder/Model/Addin/RevitAddIns.cs +++ b/Autodesk.PackageBuilder/Model/Addin/RevitAddIns.cs @@ -4,9 +4,15 @@ using System.Collections.Generic; using System.Xml; using System.Xml.Serialization; + /// + /// Represents a collection of Revit add-in definitions for XML serialization. + /// [Serializable] public class RevitAddIns : DataBase, IPackageSerializable { + /// + /// Gets or sets the list of Revit add-in models. + /// [XmlElement] public List AddIn { get; set; } = new List(); } diff --git a/Autodesk.PackageBuilder/Model/Application/ApplicationPackage.cs b/Autodesk.PackageBuilder/Model/Application/ApplicationPackage.cs index 1adc5c4..6d47f47 100644 --- a/Autodesk.PackageBuilder/Model/Application/ApplicationPackage.cs +++ b/Autodesk.PackageBuilder/Model/Application/ApplicationPackage.cs @@ -4,48 +4,93 @@ using System.Collections.Generic; using System.Xml; using System.Xml.Serialization; + /// + /// Represents an application package with metadata and components for XML serialization. + /// [Serializable] public class ApplicationPackage : DataBase, IPackageSerializable { + /// + /// Gets or sets the schema version of the application package. + /// [XmlAttribute] public string SchemaVersion { get; set; } + /// + /// Gets or sets the Autodesk product associated with this package. + /// [XmlAttribute] public string AutodeskProduct { get; set; } + /// + /// Gets or sets the name of the application package. + /// [XmlAttribute] public string Name { get; set; } + /// + /// Gets or sets the description of the application package. + /// [XmlAttribute] public string Description { get; set; } + /// + /// Gets or sets the application version. + /// [XmlAttribute] public string AppVersion { get; set; } + /// + /// Gets or sets the user-friendly version string. + /// [XmlAttribute] public string FriendlyVersion { get; set; } + /// + /// Gets or sets the product type of the application package. + /// [XmlAttribute] public string ProductType { get; set; } + /// + /// Gets or sets the product code of the application package. + /// [XmlAttribute] public string ProductCode { get; set; } + /// + /// Gets or sets the author of the application package. + /// [XmlAttribute] public string Author { get; set; } + /// + /// Gets or sets the help file associated with the application package. + /// [XmlAttribute] public string HelpFile { get; set; } + /// + /// Gets or sets the supported locales for the application package. + /// [XmlAttribute] public string SupportedLocales { get; set; } + /// + /// Gets or sets the URL to the online documentation. + /// [XmlAttribute] public string OnlineDocumentation { get; set; } + /// + /// Gets or sets the company details associated with the application package. + /// [XmlElement] public CompanyDetails CompanyDetails { get; set; } = new CompanyDetails(); + /// + /// Gets or sets the list of components included in the application package. + /// [XmlElement] public List Components { get; set; } = new List(); } diff --git a/Autodesk.PackageBuilder/Model/Application/CompanyDetails.cs b/Autodesk.PackageBuilder/Model/Application/CompanyDetails.cs index b12ded8..c44ccb5 100644 --- a/Autodesk.PackageBuilder/Model/Application/CompanyDetails.cs +++ b/Autodesk.PackageBuilder/Model/Application/CompanyDetails.cs @@ -2,21 +2,44 @@ { using System.Xml; using System.Xml.Serialization; + /// + /// Represents company information including name, URL, and optional email address. + /// public class CompanyDetails : DataBase { + /// + /// Initializes a new instance of the class. + /// public CompanyDetails() { } + + /// + /// Initializes a new instance of the class with the specified name, URL, and optional email. + /// + /// The name of the company. + /// The URL of the company. + /// The email address of the company (optional). public CompanyDetails(string name, string url, string email = null) { Name = name; Url = url; Email = email; } + + /// + /// Gets or sets the name of the company. + /// [XmlAttribute] public string Name { get; set; } + /// + /// Gets or sets the URL of the company. + /// [XmlAttribute] public string Url { get; set; } + /// + /// Gets or sets the email address of the company. + /// [XmlAttribute] public string Email { get; set; } } diff --git a/Autodesk.PackageBuilder/Model/Application/ComponentEntry.cs b/Autodesk.PackageBuilder/Model/Application/ComponentEntry.cs index f16dd1b..6f97ec4 100644 --- a/Autodesk.PackageBuilder/Model/Application/ComponentEntry.cs +++ b/Autodesk.PackageBuilder/Model/Application/ComponentEntry.cs @@ -2,9 +2,23 @@ { using System.Xml; using System.Xml.Serialization; + /// + /// Represents an application component entry with metadata for XML serialization. + /// public class ComponentEntry : DataBase { + /// + /// Initializes a new instance of the class. + /// public ComponentEntry() { } + + /// + /// Initializes a new instance of the class with the specified parameters. + /// + /// The name of the application. + /// The name of the module. + /// The version of the component (optional). + /// The description of the application (optional). public ComponentEntry(string appName, string moduleName, string version = null, string appDescription = null) { AppName = appName; @@ -12,15 +26,28 @@ public ComponentEntry(string appName, string moduleName, string version = null, Version = version; AppDescription = appDescription; } + + /// + /// Gets or sets the name of the application. + /// [XmlAttribute] public string AppName { get; set; } + /// + /// Gets or sets the name of the module. + /// [XmlAttribute] public string ModuleName { get; set; } + /// + /// Gets or sets the version of the component. + /// [XmlAttribute] public string Version { get; set; } + /// + /// Gets or sets the description of the application. + /// [XmlAttribute] public string AppDescription { get; set; } } diff --git a/Autodesk.PackageBuilder/Model/Application/Components.cs b/Autodesk.PackageBuilder/Model/Application/Components.cs index 6b6c36e..c612769 100644 --- a/Autodesk.PackageBuilder/Model/Application/Components.cs +++ b/Autodesk.PackageBuilder/Model/Application/Components.cs @@ -2,14 +2,26 @@ { using System.Xml; using System.Xml.Serialization; + /// + /// Represents a collection of application components, including runtime requirements and a component entry. + /// public class Components : DataBase { + /// + /// Gets or sets the description of the components. + /// [XmlAttribute] public string Description { get; set; } + /// + /// Gets or sets the runtime requirements for the components. + /// [XmlElement] public RuntimeRequirements RuntimeRequirements { get; set; } + /// + /// Gets or sets the component entry associated with the components. + /// [XmlElement] public ComponentEntry ComponentEntry { get; set; } } diff --git a/Autodesk.PackageBuilder/Model/Application/RuntimeRequirements.cs b/Autodesk.PackageBuilder/Model/Application/RuntimeRequirements.cs index 517f19b..ad3ddc2 100644 --- a/Autodesk.PackageBuilder/Model/Application/RuntimeRequirements.cs +++ b/Autodesk.PackageBuilder/Model/Application/RuntimeRequirements.cs @@ -2,12 +2,25 @@ { using System.Xml; using System.Xml.Serialization; + /// + /// Represents the runtime requirements for an application, including operating system, platform, and supported series range. + /// public class RuntimeRequirements : DataBase { + /// + /// Initializes a new instance of the class. + /// public RuntimeRequirements() { - } + + /// + /// Initializes a new instance of the class with the specified parameters. + /// + /// The operating system required. + /// The platform required. + /// The minimum supported series version. + /// The maximum supported series version. public RuntimeRequirements(string os, string platform, string seriesMin, string seriesMax) { OS = os; @@ -16,15 +29,27 @@ public RuntimeRequirements(string os, string platform, string seriesMin, string SeriesMax = seriesMax; } + /// + /// Gets or sets the required operating system. + /// [XmlAttribute] public string OS { get; set; } + /// + /// Gets or sets the required platform. + /// [XmlAttribute] public string Platform { get; set; } + /// + /// Gets or sets the minimum supported series version. + /// [XmlAttribute] public string SeriesMin { get; set; } + /// + /// Gets or sets the maximum supported series version. + /// [XmlAttribute] public string SeriesMax { get; set; } } diff --git a/Autodesk.PackageBuilder/Utils/BuilderUtils.cs b/Autodesk.PackageBuilder/Utils/BuilderUtils.cs index 98ebc8a..c07f4c9 100644 --- a/Autodesk.PackageBuilder/Utils/BuilderUtils.cs +++ b/Autodesk.PackageBuilder/Utils/BuilderUtils.cs @@ -19,7 +19,7 @@ public static TBuilder Build() } /// - /// Create a new instance of the type and . + /// Create a new instance of the type and . /// /// /// @@ -33,7 +33,7 @@ public static TBuilder Build(string path) } /// - /// Create a new instance of the type, the instance, and . + /// Create a new instance of the type, the instance, and . /// /// /// @@ -46,7 +46,7 @@ public static TBuilder Build(string path, Action config) } /// - /// Create a new instance of the type, the instance, and . + /// Create a new instance of the type, the instance, and . /// /// /// From 07433995fc635b410c0ba9fca7e979a31cbdd708 Mon Sep 17 00:00:00 2001 From: Luiz Henrique Cassettari Date: Fri, 16 May 2025 18:26:50 -0300 Subject: [PATCH 05/38] Add `IncludeSymbols` to support `SymbolPackageFormat` --- Autodesk.PackageBuilder/Autodesk.PackageBuilder.csproj | 3 +++ CHANGELOG.md | 1 + 2 files changed, 4 insertions(+) diff --git a/Autodesk.PackageBuilder/Autodesk.PackageBuilder.csproj b/Autodesk.PackageBuilder/Autodesk.PackageBuilder.csproj index ae68a52..cecf716 100644 --- a/Autodesk.PackageBuilder/Autodesk.PackageBuilder.csproj +++ b/Autodesk.PackageBuilder/Autodesk.PackageBuilder.csproj @@ -31,6 +31,9 @@ $(OutputPath)\$(AssemblyName).xml + true + snupkg + portable false diff --git a/CHANGELOG.md b/CHANGELOG.md index 791197a..1c8857e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [1.1.0] / 2025-05-16 ### Features - Support custom `Element` and `Attribute`. +- Add `IncludeSymbols` to support `SymbolPackageFormat`. ### PackageBuilder - Add `DataBase` with custom `IXmlSerializable`. - Add `DataBaseExtension` with `CreateEntryElement` and `CreateAttribute`. From 30d35c9dc790f113f908e06686f961b3f63410a5 Mon Sep 17 00:00:00 2001 From: Luiz Henrique Cassettari Date: Fri, 16 May 2025 18:28:59 -0300 Subject: [PATCH 06/38] Update `PrePack` --- Build/.nuke/build.schema.json | 205 +++++++++++++++++++--------------- Build/Build.cs | 2 +- build.cmd | 3 + 3 files changed, 116 insertions(+), 94 deletions(-) create mode 100644 build.cmd diff --git a/Build/.nuke/build.schema.json b/Build/.nuke/build.schema.json index a0854f5..087e3b4 100644 --- a/Build/.nuke/build.schema.json +++ b/Build/.nuke/build.schema.json @@ -1,65 +1,70 @@ { "$schema": "http://json-schema.org/draft-04/schema#", - "$ref": "#/definitions/build", - "title": "Build Schema", "definitions": { - "build": { - "type": "object", + "Host": { + "type": "string", + "enum": [ + "AppVeyor", + "AzurePipelines", + "Bamboo", + "Bitbucket", + "Bitrise", + "GitHubActions", + "GitLab", + "Jenkins", + "Rider", + "SpaceAutomation", + "TeamCity", + "Terminal", + "TravisCI", + "VisualStudio", + "VSCode" + ] + }, + "ExecutableTarget": { + "type": "string", + "enum": [ + "Build", + "Clean", + "Compile", + "CompileExample", + "GitPreRelease", + "GitRelease", + "Pack", + "PrePack", + "Release", + "Sign", + "Test" + ] + }, + "Verbosity": { + "type": "string", + "description": "", + "enum": [ + "Verbose", + "Normal", + "Minimal", + "Quiet" + ] + }, + "NukeBuild": { "properties": { "Continue": { "type": "boolean", "description": "Indicates to continue a previously failed build attempt" }, - "Folder": { - "type": "string" - }, - "GitHubToken": { - "type": "string", - "default": "Secrets must be entered via 'nuke :secrets [profile]'" - }, "Help": { "type": "boolean", "description": "Shows the help text for this build assembly" }, "Host": { - "type": "string", "description": "Host for execution. Default is 'automatic'", - "enum": [ - "AppVeyor", - "AzurePipelines", - "Bamboo", - "Bitbucket", - "Bitrise", - "GitHubActions", - "GitLab", - "Jenkins", - "Rider", - "SpaceAutomation", - "TeamCity", - "Terminal", - "TravisCI", - "VisualStudio", - "VSCode" - ] - }, - "MainName": { - "type": "string" - }, - "Name": { - "type": "string" + "$ref": "#/definitions/Host" }, "NoLogo": { "type": "boolean", "description": "Disables displaying the NUKE logo" }, - "NugetApiKey": { - "type": "string", - "default": "Secrets must be entered via 'nuke :secrets [profile]'" - }, - "NugetApiUrl": { - "type": "string", - "default": "Secrets must be entered via 'nuke :secrets [profile]'" - }, "Partition": { "type": "string", "description": "Partition to use on CI" @@ -75,6 +80,64 @@ "type": "string" } }, + "Root": { + "type": "string", + "description": "Root directory during build execution" + }, + "Skip": { + "type": "array", + "description": "List of targets to be skipped. Empty list skips all dependencies", + "items": { + "$ref": "#/definitions/ExecutableTarget" + } + }, + "Target": { + "type": "array", + "description": "List of targets to be invoked. Default is '{default_target}'", + "items": { + "$ref": "#/definitions/ExecutableTarget" + } + }, + "Verbosity": { + "description": "Logging verbosity during build execution. Default is 'Normal'", + "$ref": "#/definitions/Verbosity" + } + } + } + }, + "allOf": [ + { + "properties": { + "EnableForkedRepository": { + "type": "boolean" + }, + "Folder": { + "type": "string" + }, + "GitHubToken": { + "type": "string", + "default": "Secrets must be entered via 'nuke :secrets [profile]'" + }, + "MainName": { + "type": "string" + }, + "Name": { + "type": "string" + }, + "NuGetApiKey": { + "type": "string", + "default": "Secrets must be entered via 'nuke :secrets [profile]'" + }, + "NuGetApiUrl": { + "type": "string", + "default": "Secrets must be entered via 'nuke :secrets [profile]'" + }, + "PreReleaseFilter": { + "type": "array", + "items": { + "type": "string" + } + }, "ReleaseExample": { "type": "boolean" }, @@ -84,10 +147,6 @@ "ReleaseNameVersion": { "type": "boolean" }, - "Root": { - "type": "string", - "description": "Root directory during build execution" - }, "SignFile": { "type": "string", "default": "Secrets must be entered via 'nuke :secrets [profile]'" @@ -96,46 +155,10 @@ "type": "string", "default": "Secrets must be entered via 'nuke :secrets [profile]'" }, - "Skip": { - "type": "array", - "description": "List of targets to be skipped. Empty list skips all dependencies", - "items": { - "type": "string", - "enum": [ - "Build", - "Clean", - "Compile", - "CompileExample", - "GitRelease", - "Pack", - "Release", - "Sign", - "Test" - ] - } - }, "Solution": { "type": "string", "description": "Path to a solution file that is automatically loaded" }, - "Target": { - "type": "array", - "description": "List of targets to be invoked. Default is '{default_target}'", - "items": { - "type": "string", - "enum": [ - "Build", - "Clean", - "Compile", - "CompileExample", - "GitRelease", - "Pack", - "Release", - "Sign", - "Test" - ] - } - }, "TestBuildStopWhenFailed": { "type": "boolean" }, @@ -145,17 +168,13 @@ "TestResults": { "type": "boolean" }, - "Verbosity": { - "type": "string", - "description": "Logging verbosity during build execution. Default is 'Normal'", - "enum": [ - "Minimal", - "Normal", - "Quiet", - "Verbose" - ] + "UnlistNuGet": { + "type": "boolean" } } + }, + { + "$ref": "#/definitions/NukeBuild" } - } + ] } diff --git a/Build/Build.cs b/Build/Build.cs index fb1c8e4..f146e43 100644 --- a/Build/Build.cs +++ b/Build/Build.cs @@ -3,7 +3,7 @@ using ricaun.Nuke; using ricaun.Nuke.Components; -partial class Build : NukeBuild, IPublishPack, ICompileExample, ITest +partial class Build : NukeBuild, IPublishPack, IPrePack, ICompileExample, ITest { public static int Main() => Execute(x => x.From().Build); } \ No newline at end of file diff --git a/build.cmd b/build.cmd new file mode 100644 index 0000000..07d4307 --- /dev/null +++ b/build.cmd @@ -0,0 +1,3 @@ +cd .\Build\ +call build.cmd %* +timeout 15 \ No newline at end of file From c22d2c1e3fb3e8e3202273328dd33ead2fe94ab6 Mon Sep 17 00:00:00 2001 From: Luiz Henrique Cassettari Date: Fri, 16 May 2025 18:40:27 -0300 Subject: [PATCH 07/38] Update readme --- README.md | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 57 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 32e3f23..58f4b82 100644 --- a/README.md +++ b/README.md @@ -216,13 +216,68 @@ BuilderUtils.Build(builder => {...}, "RevitAddin.addin"); BuilderUtils.Build(builder => {...}).Build("RevitAddin.addin"); ``` +### Not implemented Attribute and Element + +If the `Attribute` or `Element` is not implemented, you can use `DataBuilder` to access the methods `CreateAttribute` and `CreateElement`. + +```C# +var builder = BuilderUtils.Build(builder => +{ + builder.Components + .CreateEntry("Revit 2021") + .DataBuilder.CreateAttribute("Attribute", "Value"); + + builder.Components + .CreateEntry("Revit 2022") + .DataBuilder.CreateElement("Element", "Value"); + + builder.Components + .CreateEntry("Revit 2023") + .DataBuilder.CreateAttribute("Attribute", "Value"); + + builder.Components + .CreateEntry("Revit 2024") + .DataBuilder.CreateElement("Element", "Value"); +}); +``` + +#### Create custom Element + +The class `DataBase` could be used to create custom `Element`. +```C# +public class CustomElement : DataBase +{ + [XmlAttribute] + public string Name { get; set; } + [XmlElement] + public string Value { get; set; } +} +``` + +The `DataBase` uses a `XmlSerializer` to serialize the object. + +```C# +var builder = BuilderUtils.Build(builder => +{ + var custom = new CustomElement() + { + Name = "Name", + Value = "Value" + }; + + builder.Components + .CreateEntry("Revit 2021") + .DataBuilder.CreateElement("CustomElement", custom); +}); +``` + ## Package Inspiration / Reference -This package was inspared by [InnoSetup.ScriptBuilder](https://github.com/ReactiveBIM/InnoSetup.ScriptBuilder) package. +This package was inspired by [InnoSetup.ScriptBuilder](https://github.com/ReactiveBIM/InnoSetup.ScriptBuilder) package. ## License -This package is [licensed](LICENSE) under the [MIT Licence](https://en.wikipedia.org/wiki/MIT_License). +This package is [licensed](LICENSE) under the [MIT License](https://en.wikipedia.org/wiki/MIT_License). --- From 457e6c852842fbc9969ad50a9eae0e113a2c7869 Mon Sep 17 00:00:00 2001 From: Luiz Henrique Cassettari Date: Fri, 16 May 2025 18:45:05 -0300 Subject: [PATCH 08/38] Update readme --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 58f4b82..cc0049d 100644 --- a/README.md +++ b/README.md @@ -2,13 +2,13 @@ This package is intended to build Autodesk `PackageContent.xml` and `RevitAddin.addin` using C# fluent API. -[![Autodesk](https://img.shields.io/badge/Autodesk-black?logo=autodesk&logoColor=white)](../..) -[![Revit](https://img.shields.io/badge/Revit-black.svg)](../..) +[![Autodesk](https://img.shields.io/badge/Autodesk-black?logo=autodesk&logoColor=white)](https://github.com/ricaun-io/Autodesk.PackageBuilder) +[![Revit](https://img.shields.io/badge/Revit-black.svg)](https://github.com/ricaun-io/Autodesk.PackageBuilder) -[![Visual Studio 2022](https://img.shields.io/badge/Visual%20Studio-2022-blue)](../..) +[![Visual Studio 2022](https://img.shields.io/badge/Visual%20Studio-2022-blue)](https://github.com/ricaun-io/Autodesk.PackageBuilder) [![Nuke](https://img.shields.io/badge/Nuke-Build-blue)](https://nuke.build/) [![License MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE) -[![Build](../../actions/workflows/Build.yml/badge.svg)](../../actions) +[![Build](https://github.com/ricaun-io/Autodesk.PackageBuilder/actions/workflows/Build.yml/badge.svg)](https://github.com/ricaun-io/Autodesk.PackageBuilder/actions) [![Release](https://img.shields.io/nuget/v/Autodesk.PackageBuilder?logo=nuget&label=release&color=blue)](https://www.nuget.org/packages/Autodesk.PackageBuilder) ## Examples @@ -281,4 +281,4 @@ This package is [licensed](LICENSE) under the [MIT License](https://en.wikipedia --- -Do you like this package? Please [star this project on GitHub](../../stargazers)! +Do you like this package? Please [star this project on GitHub](https://github.com/ricaun-io/Autodesk.PackageBuilder/stargazers)! From abbd8aaae10e3490ef527e3864e2a9291e1b2437 Mon Sep 17 00:00:00 2001 From: Luiz Henrique Cassettari Date: Tue, 27 May 2025 18:08:41 -0300 Subject: [PATCH 09/38] Update `ExtensibleData` --- .../Data/DataBuild_Tests.cs | 47 +++++++++++++++++ .../Builder/Abstractions/BuilderBase.cs | 2 +- .../Builder/Abstractions/DataBuilderBase.cs | 50 +++++++++---------- .../Builder/Abstractions/ListBuilderBase.cs | 2 +- .../Builder/Abstractions/SingleBuilderBase.cs | 2 +- .../Model/Addin/AddInApplication.cs | 2 +- .../Model/Addin/AddInModel.cs | 2 +- .../Model/Addin/RevitAddIns.cs | 2 +- .../Model/Application/ApplicationPackage.cs | 2 +- .../Model/Application/CompanyDetails.cs | 2 +- .../Model/Application/ComponentEntry.cs | 2 +- .../Model/Application/Components.cs | 2 +- .../Model/Application/RuntimeRequirements.cs | 2 +- .../Data/{DataBase.cs => ExtensibleData.cs} | 2 +- ...xtension.cs => ExtensibleDataExtension.cs} | 26 +++++----- CHANGELOG.md | 4 +- README.md | 33 +++++++++--- 17 files changed, 125 insertions(+), 59 deletions(-) rename Autodesk.PackageBuilder/Model/Data/{DataBase.cs => ExtensibleData.cs} (99%) rename Autodesk.PackageBuilder/Model/Data/{DataBaseExtension.cs => ExtensibleDataExtension.cs} (59%) diff --git a/Autodesk.PackageBuilder.Tests/Data/DataBuild_Tests.cs b/Autodesk.PackageBuilder.Tests/Data/DataBuild_Tests.cs index 1669c48..bb30030 100644 --- a/Autodesk.PackageBuilder.Tests/Data/DataBuild_Tests.cs +++ b/Autodesk.PackageBuilder.Tests/Data/DataBuild_Tests.cs @@ -1,6 +1,7 @@ using Autodesk.PackageBuilder.Model.Application; using Autodesk.PackageBuilder.Tests.Utils; using NUnit.Framework; +using System.Xml.Serialization; namespace Autodesk.PackageBuilder.Tests.Data { @@ -57,5 +58,51 @@ public void Build_CreateComponentEntry(int length) builder.AssertElementAttribute("ComponentEntry", "Attribute", i); } } + + [Test] + public void Build_CustomExtensibleData() + { + var builder = BuilderUtils.Build(builder => + { + var custom = new CustomElement() + { + Name = "Name", + Value = "Value" + }; + + var componentRevit2021 = builder.Components + .CreateEntry("Revit 2021"); + + componentRevit2021.DataBuilder.CreateAttribute("Attribute", true); + componentRevit2021.DataBuilder.CreateElement("Element", true); + componentRevit2021.DataBuilder.CreateElement("CustomElement", custom); + }); + + var result = builder.ToString(); + System.Console.WriteLine(result); + + Assert.AreEqual(Expected, result, $"Expected: {Expected}\nContent: {result}"); + } + + public class CustomElement : ExtensibleData + { + [XmlAttribute] + public string Name { get; set; } + [XmlElement] + public string Value { get; set; } + } + + public static string Expected => """" + + + + + true + + Value + + + + """"; } } \ No newline at end of file diff --git a/Autodesk.PackageBuilder/Builder/Abstractions/BuilderBase.cs b/Autodesk.PackageBuilder/Builder/Abstractions/BuilderBase.cs index f30a1ab..00d7ec0 100644 --- a/Autodesk.PackageBuilder/Builder/Abstractions/BuilderBase.cs +++ b/Autodesk.PackageBuilder/Builder/Abstractions/BuilderBase.cs @@ -10,7 +10,7 @@ /// public abstract class BuilderBase where TBuilder : class - where TData : DataBase, new() + where TData : ExtensibleData, new() { /// /// Data diff --git a/Autodesk.PackageBuilder/Builder/Abstractions/DataBuilderBase.cs b/Autodesk.PackageBuilder/Builder/Abstractions/DataBuilderBase.cs index 0574547..1f78e4f 100644 --- a/Autodesk.PackageBuilder/Builder/Abstractions/DataBuilderBase.cs +++ b/Autodesk.PackageBuilder/Builder/Abstractions/DataBuilderBase.cs @@ -1,26 +1,26 @@ namespace Autodesk.PackageBuilder { /// - /// Provides a base builder for constructing and manipulating objects. + /// Provides a base builder for constructing and manipulating objects. /// /// /// This builder offers a fluent API for creating and modifying attributes and elements - /// within a instance. It supports both direct manipulation of the + /// within a instance. It supports both direct manipulation of the /// underlying data model and creation of nested elements or attributes using generic overloads. /// - public class DataBuilderBase : SingleBuilderBase + public class DataBuilderBase : SingleBuilderBase { /// - /// Initializes a new instance of the class with the specified model. + /// Initializes a new instance of the class with the specified model. /// - /// The instance to wrap and build upon. - public DataBuilderBase(DataBase model) + /// The instance to wrap and build upon. + public DataBuilderBase(ExtensibleData model) { SetDataInternal(model); } /// - /// Creates a new data attribute with the specified name and value in the underlying . + /// Creates a new data attribute with the specified name and value in the underlying . /// /// The name of the attribute to create. /// The value of the attribute. @@ -42,33 +42,33 @@ public DataBuilderBase CreateElement(string name) } /// - /// Creates a new data element with the specified name and value in the underlying . + /// Creates a new data element with the specified name and value in the underlying . /// /// The name of the data element to create. /// - /// The value to associate with the new data element. If the value is a , it will be used to create a nested element. + /// The value to associate with the new data element. If the value is a , it will be used to create a nested element. /// Otherwise, the value will be set directly. /// /// - /// A new instance for the created data element if is a ; otherwise, null. + /// A new instance for the created data element if is a ; otherwise, null. /// public DataBuilderBase CreateElement(string name, object value) { - if (value is DataBase dataBase) - return new DataBuilderBase(Data.CreateDataElement(name, dataBase)); + if (value is ExtensibleData extensibleData) + return new DataBuilderBase(Data.CreateDataElement(name, extensibleData)); Data.CreateDataElement(name, value); return null; } /// - /// Creates a new data attribute with the specified name and value in a new instance of derived from . + /// Creates a new data attribute with the specified name and value in a new instance of derived from . /// - /// The type of to use for creating the attribute. Must have a parameterless constructor. + /// The type of to use for creating the attribute. Must have a parameterless constructor. /// The name of the attribute to create. /// The value of the attribute. /// The current instance for method chaining. - public DataBuilderBase CreateAttribute(string name, object value) where T : DataBase, new() + public DataBuilderBase CreateAttribute(string name, object value) where T : ExtensibleData, new() { var data = GetNewPropertyValue(Data); data.CreateDataAttribute(name, value); @@ -76,32 +76,32 @@ public DataBuilderBase CreateElement(string name, object value) } /// - /// Creates a new data element with the specified name in a new instance of derived from . + /// Creates a new data element with the specified name in a new instance of derived from . /// - /// The type of to use for creating the element. Must have a parameterless constructor. + /// The type of to use for creating the element. Must have a parameterless constructor. /// The name of the data element to create. /// A new instance for the created data element. - public DataBuilderBase CreateElement(string name) where T : DataBase, new() + public DataBuilderBase CreateElement(string name) where T : ExtensibleData, new() { var data = GetNewPropertyValue(Data); return new DataBuilderBase(data.CreateDataElement(name)); } /// - /// Creates a new data element with the specified name and value in a new instance of derived from . + /// Creates a new data element with the specified name and value in a new instance of derived from . /// - /// The type of to use for creating the element. Must have a parameterless constructor. + /// The type of to use for creating the element. Must have a parameterless constructor. /// The name of the data element to create. - /// The value to associate with the new data element. If the value is a , it will be used to create a nested element. + /// The value to associate with the new data element. If the value is a , it will be used to create a nested element. /// - /// A new instance for the created data element if is a ; otherwise, null. + /// A new instance for the created data element if is a ; otherwise, null. /// - public DataBuilderBase CreateElement(string name, object value) where T : DataBase, new() + public DataBuilderBase CreateElement(string name, object value) where T : ExtensibleData, new() { var data = GetNewPropertyValue(Data); - if (value is DataBase dataBase) - return new DataBuilderBase(data.CreateDataElement(name, dataBase)); + if (value is ExtensibleData extensibleData) + return new DataBuilderBase(data.CreateDataElement(name, extensibleData)); data.CreateDataElement(name, value); return null; diff --git a/Autodesk.PackageBuilder/Builder/Abstractions/ListBuilderBase.cs b/Autodesk.PackageBuilder/Builder/Abstractions/ListBuilderBase.cs index d69eaea..4c0ab36 100644 --- a/Autodesk.PackageBuilder/Builder/Abstractions/ListBuilderBase.cs +++ b/Autodesk.PackageBuilder/Builder/Abstractions/ListBuilderBase.cs @@ -8,7 +8,7 @@ /// public abstract class ListBuilderBase : BuilderBase where TBuilder : class - where TData : DataBase, new() + where TData : ExtensibleData, new() { private List _entryList; diff --git a/Autodesk.PackageBuilder/Builder/Abstractions/SingleBuilderBase.cs b/Autodesk.PackageBuilder/Builder/Abstractions/SingleBuilderBase.cs index 65a6f89..58ba552 100644 --- a/Autodesk.PackageBuilder/Builder/Abstractions/SingleBuilderBase.cs +++ b/Autodesk.PackageBuilder/Builder/Abstractions/SingleBuilderBase.cs @@ -7,7 +7,7 @@ /// public abstract class SingleBuilderBase : BuilderBase where TBuilder : class - where TData : DataBase, new() + where TData : ExtensibleData, new() { /// /// SetDataInternal diff --git a/Autodesk.PackageBuilder/Model/Addin/AddInApplication.cs b/Autodesk.PackageBuilder/Model/Addin/AddInApplication.cs index 8d57680..a3f44cd 100644 --- a/Autodesk.PackageBuilder/Model/Addin/AddInApplication.cs +++ b/Autodesk.PackageBuilder/Model/Addin/AddInApplication.cs @@ -5,7 +5,7 @@ /// /// Represents an add-in application definition for Autodesk products. /// - public class AddInApplication : DataBase + public class AddInApplication : ExtensibleData { /// /// Gets or sets the type of the add-in application. diff --git a/Autodesk.PackageBuilder/Model/Addin/AddInModel.cs b/Autodesk.PackageBuilder/Model/Addin/AddInModel.cs index 93f9a71..fb8692c 100644 --- a/Autodesk.PackageBuilder/Model/Addin/AddInModel.cs +++ b/Autodesk.PackageBuilder/Model/Addin/AddInModel.cs @@ -5,7 +5,7 @@ /// /// Represents an add-in model for Autodesk Package Builder, containing metadata for an add-in. /// - public class AddInModel : DataBase + public class AddInModel : ExtensibleData { /// /// Gets or sets the type of the add-in. diff --git a/Autodesk.PackageBuilder/Model/Addin/RevitAddIns.cs b/Autodesk.PackageBuilder/Model/Addin/RevitAddIns.cs index 017c41a..337abfa 100644 --- a/Autodesk.PackageBuilder/Model/Addin/RevitAddIns.cs +++ b/Autodesk.PackageBuilder/Model/Addin/RevitAddIns.cs @@ -8,7 +8,7 @@ /// Represents a collection of Revit add-in definitions for XML serialization. /// [Serializable] - public class RevitAddIns : DataBase, IPackageSerializable + public class RevitAddIns : ExtensibleData, IPackageSerializable { /// /// Gets or sets the list of Revit add-in models. diff --git a/Autodesk.PackageBuilder/Model/Application/ApplicationPackage.cs b/Autodesk.PackageBuilder/Model/Application/ApplicationPackage.cs index 6d47f47..d0873c9 100644 --- a/Autodesk.PackageBuilder/Model/Application/ApplicationPackage.cs +++ b/Autodesk.PackageBuilder/Model/Application/ApplicationPackage.cs @@ -8,7 +8,7 @@ /// Represents an application package with metadata and components for XML serialization. /// [Serializable] - public class ApplicationPackage : DataBase, IPackageSerializable + public class ApplicationPackage : ExtensibleData, IPackageSerializable { /// /// Gets or sets the schema version of the application package. diff --git a/Autodesk.PackageBuilder/Model/Application/CompanyDetails.cs b/Autodesk.PackageBuilder/Model/Application/CompanyDetails.cs index c44ccb5..8a80b9d 100644 --- a/Autodesk.PackageBuilder/Model/Application/CompanyDetails.cs +++ b/Autodesk.PackageBuilder/Model/Application/CompanyDetails.cs @@ -5,7 +5,7 @@ /// /// Represents company information including name, URL, and optional email address. /// - public class CompanyDetails : DataBase + public class CompanyDetails : ExtensibleData { /// /// Initializes a new instance of the class. diff --git a/Autodesk.PackageBuilder/Model/Application/ComponentEntry.cs b/Autodesk.PackageBuilder/Model/Application/ComponentEntry.cs index 6f97ec4..0a62fd1 100644 --- a/Autodesk.PackageBuilder/Model/Application/ComponentEntry.cs +++ b/Autodesk.PackageBuilder/Model/Application/ComponentEntry.cs @@ -5,7 +5,7 @@ /// /// Represents an application component entry with metadata for XML serialization. /// - public class ComponentEntry : DataBase + public class ComponentEntry : ExtensibleData { /// /// Initializes a new instance of the class. diff --git a/Autodesk.PackageBuilder/Model/Application/Components.cs b/Autodesk.PackageBuilder/Model/Application/Components.cs index c612769..6b414da 100644 --- a/Autodesk.PackageBuilder/Model/Application/Components.cs +++ b/Autodesk.PackageBuilder/Model/Application/Components.cs @@ -5,7 +5,7 @@ /// /// Represents a collection of application components, including runtime requirements and a component entry. /// - public class Components : DataBase + public class Components : ExtensibleData { /// /// Gets or sets the description of the components. diff --git a/Autodesk.PackageBuilder/Model/Application/RuntimeRequirements.cs b/Autodesk.PackageBuilder/Model/Application/RuntimeRequirements.cs index ad3ddc2..f5cadbd 100644 --- a/Autodesk.PackageBuilder/Model/Application/RuntimeRequirements.cs +++ b/Autodesk.PackageBuilder/Model/Application/RuntimeRequirements.cs @@ -5,7 +5,7 @@ /// /// Represents the runtime requirements for an application, including operating system, platform, and supported series range. /// - public class RuntimeRequirements : DataBase + public class RuntimeRequirements : ExtensibleData { /// /// Initializes a new instance of the class. diff --git a/Autodesk.PackageBuilder/Model/Data/DataBase.cs b/Autodesk.PackageBuilder/Model/Data/ExtensibleData.cs similarity index 99% rename from Autodesk.PackageBuilder/Model/Data/DataBase.cs rename to Autodesk.PackageBuilder/Model/Data/ExtensibleData.cs index 18a20d8..c489e3d 100644 --- a/Autodesk.PackageBuilder/Model/Data/DataBase.cs +++ b/Autodesk.PackageBuilder/Model/Data/ExtensibleData.cs @@ -10,7 +10,7 @@ namespace Autodesk.PackageBuilder; /// /// Represents a base class for XML-serializable data models, supporting dynamic attributes and elements. /// -public class DataBase : IXmlSerializable +public class ExtensibleData : IXmlSerializable { /// /// Gets the auxiliary dictionary for storing additional attributes and elements. diff --git a/Autodesk.PackageBuilder/Model/Data/DataBaseExtension.cs b/Autodesk.PackageBuilder/Model/Data/ExtensibleDataExtension.cs similarity index 59% rename from Autodesk.PackageBuilder/Model/Data/DataBaseExtension.cs rename to Autodesk.PackageBuilder/Model/Data/ExtensibleDataExtension.cs index 5931848..d7a0ab7 100644 --- a/Autodesk.PackageBuilder/Model/Data/DataBaseExtension.cs +++ b/Autodesk.PackageBuilder/Model/Data/ExtensibleDataExtension.cs @@ -1,46 +1,46 @@ namespace Autodesk.PackageBuilder; /// -/// Provides extension methods for the class to add dynamic attributes and elements. +/// Provides extension methods for the class to add dynamic attributes and elements. /// -public static class DataBaseExtension +public static class ExtensibleDataExtension { /// - /// Adds an attribute to the model. + /// Adds an attribute to the model. /// - /// A type derived from . + /// A type derived from . /// The model to which the attribute will be added. /// The name of the attribute. /// The value of the attribute. /// The modified model instance. - public static T CreateDataAttribute(this T model, string name, object value) where T : DataBase + public static T CreateDataAttribute(this T model, string name, object value) where T : ExtensibleData { model.Auxiliary.Add(name, (value, false)); return model; } /// - /// Adds a new entry element with the specified name to the model. + /// Adds a new entry element with the specified name to the model. /// - /// A type derived from . + /// A type derived from . /// The model to which the entry element will be added. /// The name of the entry element. - /// The newly created entry element. - public static DataBase CreateDataElement(this T model, string name) where T : DataBase + /// The newly created entry element. + public static ExtensibleData CreateDataElement(this T model, string name) where T : ExtensibleData { - return model.CreateDataElement(name, new DataBase()); + return model.CreateDataElement(name, new ExtensibleData()); } /// - /// Adds a new entry element with the specified name and value to the model. + /// Adds a new entry element with the specified name and value to the model. /// - /// A type derived from . + /// A type derived from . /// The type of the entry element value. /// The model to which the entry element will be added. /// The name of the entry element. /// The value of the entry element. /// The entry element value. - public static TElement CreateDataElement(this T model, string name, TElement value) where T : DataBase + public static TElement CreateDataElement(this T model, string name, TElement value) where T : ExtensibleData { model.Auxiliary.Add(name, (value, true)); return value; diff --git a/CHANGELOG.md b/CHANGELOG.md index 1c8857e..97b6d60 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,8 +9,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Support custom `Element` and `Attribute`. - Add `IncludeSymbols` to support `SymbolPackageFormat`. ### PackageBuilder -- Add `DataBase` with custom `IXmlSerializable`. -- Add `DataBaseExtension` with `CreateEntryElement` and `CreateAttribute`. +- Add `ExtensibleData` with custom `IXmlSerializable`. +- Add `ExtensibleDataExtension` with `CreateEntryElement` and `CreateAttribute`. - Add `DataBuilderBase` and `DataBuilderBaseExtension`. ### Tests - Add `DataBuild_Tests` to test `DataBuilder` diff --git a/README.md b/README.md index cc0049d..b98a28a 100644 --- a/README.md +++ b/README.md @@ -241,11 +241,11 @@ var builder = BuilderUtils.Build(builder => }); ``` -#### Create custom Element +#### Create custom Element/Attribute -The class `DataBase` could be used to create custom `Element`. +The class `ExtensibleData` could be used to create custom `Element`. ```C# -public class CustomElement : DataBase +public class CustomElement : ExtensibleData { [XmlAttribute] public string Name { get; set; } @@ -254,7 +254,8 @@ public class CustomElement : DataBase } ``` -The `DataBase` uses a `XmlSerializer` to serialize the object. +The `ExtensibleData` uses a `XmlSerializer` to serialize the object. +Use the `DataBuilder` to access the methods `CreateElement` and `CreateAttribute` to create custom elements or attributes. ```C# var builder = BuilderUtils.Build(builder => @@ -265,12 +266,30 @@ var builder = BuilderUtils.Build(builder => Value = "Value" }; - builder.Components - .CreateEntry("Revit 2021") - .DataBuilder.CreateElement("CustomElement", custom); + var componentRevit2021 = builder.Components + .CreateEntry("Revit 2021"); + + componentRevit2021.DataBuilder.CreateAttribute("Attribute", true); + componentRevit2021.DataBuilder.CreateElement("Element", true); + componentRevit2021.DataBuilder.CreateElement("CustomElement", custom); }); ``` +This is the result of the above code: + +```xml + + + + + true + + Value + + + +``` + ## Package Inspiration / Reference This package was inspired by [InnoSetup.ScriptBuilder](https://github.com/ReactiveBIM/InnoSetup.ScriptBuilder) package. From 49f59b96b80be0d6c5b8f4988e4ea492cd26c25f Mon Sep 17 00:00:00 2001 From: Luiz Henrique Cassettari Date: Tue, 27 May 2025 18:08:56 -0300 Subject: [PATCH 10/38] Version 1.1.0-beta --- Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Build.props b/Directory.Build.props index ce2e08d..630c6cc 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,5 +1,5 @@ - 1.1.0-alpha + 1.1.0-beta \ No newline at end of file From b970ef28342809ffb0f64bb4a3610bd5868e70ab Mon Sep 17 00:00:00 2001 From: Luiz Henrique Cassettari Date: Wed, 28 May 2025 09:38:31 -0300 Subject: [PATCH 11/38] Add `AutoCADUtils` and `AutoCADExtensibleData` --- .../AutoCAD/AutoCADExtensibleData.cs | 70 +++++++++++ Autodesk.PackageBuilder/Utils/AutoCADUtils.cs | 119 ++++++++++++++++++ Autodesk.PackageBuilder/Utils/RevitUtils.cs | 78 +++++++----- CHANGELOG.md | 2 + 4 files changed, 241 insertions(+), 28 deletions(-) create mode 100644 Autodesk.PackageBuilder/Extensible/AutoCAD/AutoCADExtensibleData.cs create mode 100644 Autodesk.PackageBuilder/Utils/AutoCADUtils.cs diff --git a/Autodesk.PackageBuilder/Extensible/AutoCAD/AutoCADExtensibleData.cs b/Autodesk.PackageBuilder/Extensible/AutoCAD/AutoCADExtensibleData.cs new file mode 100644 index 0000000..72e6d27 --- /dev/null +++ b/Autodesk.PackageBuilder/Extensible/AutoCAD/AutoCADExtensibleData.cs @@ -0,0 +1,70 @@ +using Autodesk.PackageBuilder.Model.Application; + +namespace Autodesk.PackageBuilder.Extensible.AutoCAD; + +/// +/// Provides extension methods for configuring AutoCAD-specific extensible data on instances. +/// +/// +/// For more information, see the AutoCAD Developer Documentation: +/// https://help.autodesk.com/view/OARX/2025/ENU/?guid=GUID-3C25E517-8660-4BB7-9447-2310462EF06F +/// +public static class AutoCADExtensibleData +{ + /// + /// Sets the LoadOnAppearance attribute for the current in the entry. + /// + /// The instance to configure. + /// A value indicating whether the component should load on appearance. + /// The current instance for further configuration. + /// + /// LoadOnAppearance. Load when the product detects the application bundle in one of the ApplicationPlugins folders, thereby supporting instant load on installation with no need to restart the AutoCAD-based product. The parameter behaves the same way as LoadOnAutoCADStartup except the load context is relevant to when an application is installed while the product is running, for instance if installed via the Autodesk App Store website. + /// + public static ComponentsBuilder LoadOnAppearance(this ComponentsBuilder componentsBuilder, bool value) + { + componentsBuilder.DataBuilder.CreateAttribute("LoadOnAppearance", value); + return componentsBuilder; + } + + /// + /// Adds command definitions to the current in the entry. + /// + /// The instance to configure. + /// An array of command names to add as both global and local commands. + /// The current instance for further configuration. + public static ComponentsBuilder Commands(this ComponentsBuilder componentsBuilder, params string[] globalLocalCommands) + { + return componentsBuilder.Commands(string.Empty, globalLocalCommands); + } + + /// + /// Adds command definitions to the current in the entry, optionally grouping them. + /// + /// The instance to configure. + /// The group name for the commands, or an empty string for no group. + /// An array of command names to add as both global and local commands. + /// The current instance for further configuration. + public static ComponentsBuilder Commands(this ComponentsBuilder componentsBuilder, string groupName, params string[] globalLocalCommands) + { + if (globalLocalCommands.Length == 0) + return componentsBuilder; + + var commandEntry = componentsBuilder.DataBuilder.CreateElement("Commands"); + + if (!string.IsNullOrWhiteSpace(groupName)) + { + commandEntry.CreateAttribute("GroupName", groupName); + } + + foreach (var globalLocalCommand in globalLocalCommands) + { + if (!string.IsNullOrWhiteSpace(globalLocalCommand)) continue; + + commandEntry.CreateElement("Command") + .CreateAttribute("Global", globalLocalCommand) + .CreateAttribute("Local", globalLocalCommand); + } + + return componentsBuilder; + } +} diff --git a/Autodesk.PackageBuilder/Utils/AutoCADUtils.cs b/Autodesk.PackageBuilder/Utils/AutoCADUtils.cs new file mode 100644 index 0000000..6a01d23 --- /dev/null +++ b/Autodesk.PackageBuilder/Utils/AutoCADUtils.cs @@ -0,0 +1,119 @@ +using System; + +namespace Autodesk.PackageBuilder; + +/// +/// Provides utility extension methods for configuring AutoCAD-specific application packages and components. +/// +/// +/// For more information, see the AutoCAD Developer Documentation: +/// https://help.autodesk.com/view/OARX/2025/ENU/?guid=GUID-BC76355D-682B-46ED-B9B7-66C95EEF2BD0 +/// +public static class AutoCADUtils +{ + private const string Os = "Win64"; + private const string Platform = "AutoCAD*"; // AutoCAD* - All AutoCAD-based products + + /// + /// Configures the for an AutoCAD application package. + /// + /// The application package builder instance. + /// The instance for chaining. + public static ApplicationPackageBuilder AutoCADApplication(this ApplicationPackageBuilder applicationPackageBuilder) + { + return applicationPackageBuilder + .ProductType(ProductTypes.Application) + .AutodeskProduct(AutodeskProducts.AutoCAD); + } + + /// + /// Configures the for the specified AutoCAD version on Windows 64-bit. + /// + /// The components builder instance. + /// The AutoCAD version. + /// The instance for chaining. + /// + /// The platform is set to "AutoCAD*" to include all AutoCAD-based products. + /// + public static ComponentsBuilder AutoCADPlatform(this ComponentsBuilder componentsBuilder, Version autoCADVersion) + { + return componentsBuilder.AutoCADPlatform(Os, Platform, autoCADVersion); + } + + /// + /// Configures the for the specified OS, platform, and AutoCAD version. + /// + /// The components builder instance. + /// The operating system (e.g., "Win64"). + /// The platform (e.g., "AutoCAD*"). + /// The AutoCAD version. + /// The instance for chaining. + /// + /// For more information, see the AutoCAD Developer Documentation: + /// https://help.autodesk.com/view/OARX/2024/ENU/?guid=GUID-1591CA01-EF87-48CD-952B-772FE26037F1 + /// + public static ComponentsBuilder AutoCADPlatform(this ComponentsBuilder componentsBuilder, string os, string platform, Version autoCADVersion) + { + return componentsBuilder.AutoCADPlatform(os, platform, autoCADVersion, autoCADVersion); + } + + /// + /// Configures the for a range of AutoCAD versions on Windows 64-bit. + /// + /// The components builder instance. + /// The minimum AutoCAD version. + /// The maximum AutoCAD version. + /// If true, sets the maximum version to one less than . + /// The instance for chaining. + /// + /// The platform is set to "AutoCAD*" to include all AutoCAD-based products. + /// + public static ComponentsBuilder AutoCADPlatform(this ComponentsBuilder componentsBuilder, Version minVersion, Version maxVersion, bool maxVersionMinusOne = false) + { + return componentsBuilder.AutoCADPlatform(Os, Platform, minVersion, maxVersion, maxVersionMinusOne); + } + + /// + /// Configures the for a range of AutoCAD versions, with options for OS, platform, and version range. + /// + /// The components builder instance. + /// The operating system (e.g., "Win64"). + /// The platform (e.g., "AutoCAD*"). + /// The minimum AutoCAD version. + /// The maximum AutoCAD version. + /// If true, sets the maximum version to one less than . + /// The instance for chaining. + /// + /// For more information, see the AutoCAD Developer Documentation: + /// https://help.autodesk.com/view/OARX/2024/ENU/?guid=GUID-1591CA01-EF87-48CD-952B-772FE26037F1 + /// + public static ComponentsBuilder AutoCADPlatform(this ComponentsBuilder componentsBuilder, string os, string platform, Version minVersion, Version maxVersion, bool maxVersionMinusOne = false) + { + var minVersionString = "R" + minVersion.ToString(2); + var maxVersionString = "R" + maxVersion?.ToString(2); + + componentsBuilder + .OS(os) + .Platform(platform) + .SeriesMin(minVersionString); + + if (maxVersion is null) + return componentsBuilder; + + componentsBuilder.SeriesMax(maxVersionString); + + if (minVersionString == maxVersionString) + return componentsBuilder; + + if (maxVersionMinusOne) + { + var maxVersionMinus = maxVersion.Minor == 0 ? + new Version(maxVersion.Major - 1, 9) : + new Version(maxVersion.Major, maxVersion.Minor - 1); + + componentsBuilder.SeriesMax("R" + maxVersionMinus.ToString(2)); + } + + return componentsBuilder; + } +} diff --git a/Autodesk.PackageBuilder/Utils/RevitUtils.cs b/Autodesk.PackageBuilder/Utils/RevitUtils.cs index 4b1f239..4388df0 100644 --- a/Autodesk.PackageBuilder/Utils/RevitUtils.cs +++ b/Autodesk.PackageBuilder/Utils/RevitUtils.cs @@ -1,36 +1,58 @@ -namespace Autodesk.PackageBuilder +namespace Autodesk.PackageBuilder; + +/// +/// Provides extension methods for configuring and for Autodesk Revit. +/// +public static class RevitUtils { + private const string Os = "Win64"; + private const string Platform = "Revit"; + /// - /// RevitUtils + /// Configures the for Autodesk Revit as an application product type. /// - public static class RevitUtils + /// The instance to configure. + /// + /// The configured instance with + /// as the product type and + /// as the Autodesk product. + /// + public static ApplicationPackageBuilder RevitApplication(this ApplicationPackageBuilder applicationPackageBuilder) { - /// - /// Set AutodeskProduct to and ProductType to . - /// - /// - /// - public static ApplicationPackageBuilder RevitApplication(this ApplicationPackageBuilder applicationPackageBuilder) - { - return applicationPackageBuilder - .ProductType(ProductTypes.Application) - .AutodeskProduct(AutodeskProducts.Revit); - } + return applicationPackageBuilder + .ProductType(ProductTypes.Application) + .AutodeskProduct(AutodeskProducts.Revit); + } - /// - /// Set Win64 / Revit / R / R - /// - /// - /// - /// - public static ComponentsBuilder RevitPlatform(this ComponentsBuilder componentsBuilder, int revitVersion) - { - return componentsBuilder - .OS("Win64") - .Platform("Revit") - .SeriesMin("R" + revitVersion) - .SeriesMax("R" + revitVersion); - } + /// + /// Configures the for the specified Revit version, using "Win64" as the OS and "Revit" as the platform. + /// + /// The instance to configure. + /// The Revit version (e.g., 2024). + /// + /// The configured instance with the specified Revit version, "Win64" OS, and "Revit" platform. + /// + public static ComponentsBuilder RevitPlatform(this ComponentsBuilder componentsBuilder, int revitVersion) + { + return componentsBuilder.RevitPlatform(Os, Platform, revitVersion); } + /// + /// Configures the for the specified OS, platform, and Revit version. + /// + /// The instance to configure. + /// The operating system (e.g., "Win64"). + /// The platform (e.g., "Revit"). + /// The Revit version (e.g., 2024). + /// + /// The configured instance with the specified OS, platform, and Revit version. + /// + public static ComponentsBuilder RevitPlatform(this ComponentsBuilder componentsBuilder, string os, string platform, int revitVersion) + { + return componentsBuilder + .OS(os) + .Platform(platform) + .SeriesMin("R" + revitVersion) + .SeriesMax("R" + revitVersion); + } } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 97b6d60..0aa4c3e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Add `ExtensibleData` with custom `IXmlSerializable`. - Add `ExtensibleDataExtension` with `CreateEntryElement` and `CreateAttribute`. - Add `DataBuilderBase` and `DataBuilderBaseExtension`. +- Add `AutoCADUtils` to support `AutoCADApplication` and `AutoCADPlatform`. +- Add `AutoCADExtensibleData` to support `LoadOnAppearance` and `Commands`. ### Tests - Add `DataBuild_Tests` to test `DataBuilder` From f9973ea2d0452c35a864dfa3327d5414c025662e Mon Sep 17 00:00:00 2001 From: Luiz Henrique Cassettari Date: Wed, 28 May 2025 11:06:13 -0300 Subject: [PATCH 12/38] Add Tests `PackageContentsBuilder_AutoCAD_Tests` --- .../PackageContentsBuilder_AutoCAD_Tests.cs | 135 ++++++++++++++++++ .../PackageContentsBuilder_Revit_Tests.cs | 66 +++++++++ .../PackageContentsBuilder_Tests.cs | 59 -------- .../AutoCAD/AutoCADExtensibleData.cs | 71 +++++++-- Autodesk.PackageBuilder/Utils/AutoCADUtils.cs | 93 ++++++++++++ CHANGELOG.md | 2 + 6 files changed, 355 insertions(+), 71 deletions(-) create mode 100644 Autodesk.PackageBuilder.Tests/Application/PackageContentsBuilder_AutoCAD_Tests.cs create mode 100644 Autodesk.PackageBuilder.Tests/Application/PackageContentsBuilder_Revit_Tests.cs diff --git a/Autodesk.PackageBuilder.Tests/Application/PackageContentsBuilder_AutoCAD_Tests.cs b/Autodesk.PackageBuilder.Tests/Application/PackageContentsBuilder_AutoCAD_Tests.cs new file mode 100644 index 0000000..fc05baa --- /dev/null +++ b/Autodesk.PackageBuilder.Tests/Application/PackageContentsBuilder_AutoCAD_Tests.cs @@ -0,0 +1,135 @@ +using NUnit.Framework; +using Autodesk.PackageBuilder.Extensible.AutoCAD; +using System; +using System.Linq; + +namespace Autodesk.PackageBuilder.Tests.Application +{ + public class PackageContentsBuilder_AutoCAD_Tests + { + [Test] + public void Build_PackageBuilder_AutoCADClass() + { + var builder = BuilderUtils.Build(); + var content = builder.ToString(); + Console.WriteLine(content); +#if NET6_0 + if (AutoCADPackageBuilder.Expected.Equals(content) == false) + Assert.Ignore("Not equal, order not match in version net6.0 for some reason..."); +#endif + Assert.AreEqual(AutoCADPackageBuilder.Expected, content, $"Expected: {AutoCADPackageBuilder.Expected}\nContent: {content}"); + } + + public class AutoCADPackageBuilder : PackageContentsBuilder + { + public static string Expected => """" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + """"; + public AutoCADPackageBuilder() + { + var commends = new[] { "CommandOpen", "CommandClose" }; + var commandGroup = "Group"; + + ApplicationPackage + .Create() + .AutoCADApplication() + .Name("AutoCADAddin") + .AppVersion("1.0.0"); + + CompanyDetails + .Create("Company Name") + .Url("url") + .Email("email"); + + Components + .CreateEntry("AutoCAD 21.0") + .OS("Win64") + .Platform("AutoCAD*") + .SeriesMin("R21.0") + .SeriesMax("R21.0") + .AppDescription("AutoCAD Addin for 2017 version") + .AppName("AutoCADAddin") + .ModuleName(@"./Contents/2017/AutoCADAddin.dll") + .Commands(); + + Components + .CreateEntry("AutoCAD 22.0") + .AutoCADPlatform("22.0") + .AppDescription("AutoCAD Addin for 2018 version") + .AppName("AutoCADAddin") + .ModuleName(@"./Contents/2018/AutoCADAddin.dll") + .CommandGroups(commandGroup, commends); + + Components + .CreateEntry("AutoCAD 23.0") + .AutoCADPlatform("23.0", "23.1") + .AppDescription("AutoCAD Addin for 2019 and 2020 versions") + .AppName("AutoCADAddin") + .ModuleName(@"./Contents/2019/AutoCADAddin.dll") + .LoadOnAppearance(false) + .Commands(commends); + + Components + .CreateEntry("AutoCAD 24.0") + .AutoCADPlatform("24.0", "25.0", true) + .AppDescription("AutoCAD Addin for 2021 to 2024 versions") + .AppName("AutoCADAddin") + .ModuleName(@"./Contents/2021/AutoCADAddin.dll") + .LoadOnAppearance() + .Commands(commends); + + Components + .CreateEntry("AutoCAD 25.0") + .AutoCADPlatform("25.0", null) + .AppDescription("AutoCAD Addin for 2025 and later versions") + .AppName("AutoCADAddin") + .ModuleName(@"./Contents/2025/AutoCADAddin.dll") + .LoadOnAppearance() + .Commands(commends.Skip(1)); + + } + } + } +} \ No newline at end of file diff --git a/Autodesk.PackageBuilder.Tests/Application/PackageContentsBuilder_Revit_Tests.cs b/Autodesk.PackageBuilder.Tests/Application/PackageContentsBuilder_Revit_Tests.cs new file mode 100644 index 0000000..c122354 --- /dev/null +++ b/Autodesk.PackageBuilder.Tests/Application/PackageContentsBuilder_Revit_Tests.cs @@ -0,0 +1,66 @@ +using NUnit.Framework; + +namespace Autodesk.PackageBuilder.Tests.Application +{ + public class PackageContentsBuilder_Revit_Tests + { + [Test] + public void Build_PackageBuilder_RevitClass() + { + var builder = BuilderUtils.Build(); + var content = builder.ToString(); +#if NET6_0 + if (RevitPackageBuilder.Expected.Equals(content) == false) + Assert.Ignore("Not equal, order not match in version net6.0 for some reason..."); +#endif + Assert.AreEqual(RevitPackageBuilder.Expected, content, $"Expected: {RevitPackageBuilder.Expected}\nContent: {content}"); + } + + public class RevitPackageBuilder : PackageContentsBuilder + { + public static string Expected => """" + + + + + + + + + + + + + """"; + public RevitPackageBuilder() + { + ApplicationPackage + .Create() + .AutodeskProduct(AutodeskProducts.Revit) + .Name("RevitAddin") + .AppVersion("1.0.0") + .ProductType(ProductTypes.Application); + + CompanyDetails + .Create("Company Name") + .Url("url") + .Email("email"); + + Components + .CreateEntry("Revit 2021") + .OS("Win64") + .Platform("Revit") + .SeriesMin("R2021") + .SeriesMax("R2021") + .AppName("RevitAddin") + .ModuleName(@"./Contents/2021/RevitAddin.addin"); + + Components + .CreateEntry("Revit 2022") + .RevitPlatform(2022) + .AppName("RevitAddin") + .ModuleName(@"./Contents/2022/RevitAddin.addin"); + } + } + } +} \ No newline at end of file diff --git a/Autodesk.PackageBuilder.Tests/Application/PackageContentsBuilder_Tests.cs b/Autodesk.PackageBuilder.Tests/Application/PackageContentsBuilder_Tests.cs index b246ecc..8981464 100644 --- a/Autodesk.PackageBuilder.Tests/Application/PackageContentsBuilder_Tests.cs +++ b/Autodesk.PackageBuilder.Tests/Application/PackageContentsBuilder_Tests.cs @@ -159,64 +159,5 @@ public void Build_Components_CreateEntry_Attribute(string value) builder.AssertAttribute("Version", value); builder.AssertAttribute("AppDescription", value); } - - [Test] - public void Build_PackageBuilder_DemoClass() - { - var builder = BuilderUtils.Build(); - var content = builder.ToString(); -#if NET6_0 - if (DemoPackageBuilder.Expected.Equals(content) == false) - Assert.Ignore("Not equal, order not match in version net6.0 for some reason..."); -#endif - Assert.AreEqual(DemoPackageBuilder.Expected, content, $"Expected: {DemoPackageBuilder.Expected}\nContent: {content}"); - } - - public class DemoPackageBuilder : PackageContentsBuilder - { - public static string Expected => """" - - - - - - - - - - - - - """"; - public DemoPackageBuilder() - { - ApplicationPackage - .Create() - .AutodeskProduct(AutodeskProducts.Revit) - .Name("RevitAddin") - .AppVersion("1.0.0") - .ProductType(ProductTypes.Application); - - CompanyDetails - .Create("Company Name") - .Url("url") - .Email("email"); - - Components - .CreateEntry("Revit 2021") - .OS("Win64") - .Platform("Revit") - .SeriesMin("R2021") - .SeriesMax("R2021") - .AppName("RevitAddin") - .ModuleName(@"./Contents/2021/RevitAddin.addin"); - - Components - .CreateEntry("Revit 2022") - .RevitPlatform(2022) - .AppName("RevitAddin") - .ModuleName(@"./Contents/2022/RevitAddin.addin"); - } - } } } \ No newline at end of file diff --git a/Autodesk.PackageBuilder/Extensible/AutoCAD/AutoCADExtensibleData.cs b/Autodesk.PackageBuilder/Extensible/AutoCAD/AutoCADExtensibleData.cs index 72e6d27..e7b6bc4 100644 --- a/Autodesk.PackageBuilder/Extensible/AutoCAD/AutoCADExtensibleData.cs +++ b/Autodesk.PackageBuilder/Extensible/AutoCAD/AutoCADExtensibleData.cs @@ -1,4 +1,7 @@ using Autodesk.PackageBuilder.Model.Application; +using System.Collections.Generic; +using System.Linq; +using System.Xml.Serialization; namespace Autodesk.PackageBuilder.Extensible.AutoCAD; @@ -9,7 +12,7 @@ namespace Autodesk.PackageBuilder.Extensible.AutoCAD; /// For more information, see the AutoCAD Developer Documentation: /// https://help.autodesk.com/view/OARX/2025/ENU/?guid=GUID-3C25E517-8660-4BB7-9447-2310462EF06F /// -public static class AutoCADExtensibleData +public static partial class AutoCADExtensibleData { /// /// Sets the LoadOnAppearance attribute for the current in the entry. @@ -20,7 +23,7 @@ public static class AutoCADExtensibleData /// /// LoadOnAppearance. Load when the product detects the application bundle in one of the ApplicationPlugins folders, thereby supporting instant load on installation with no need to restart the AutoCAD-based product. The parameter behaves the same way as LoadOnAutoCADStartup except the load context is relevant to when an application is installed while the product is running, for instance if installed via the Autodesk App Store website. /// - public static ComponentsBuilder LoadOnAppearance(this ComponentsBuilder componentsBuilder, bool value) + public static ComponentsBuilder LoadOnAppearance(this ComponentsBuilder componentsBuilder, bool value = true) { componentsBuilder.DataBuilder.CreateAttribute("LoadOnAppearance", value); return componentsBuilder; @@ -32,9 +35,9 @@ public static ComponentsBuilder LoadOnAppearance(this ComponentsBuilder componen /// The instance to configure. /// An array of command names to add as both global and local commands. /// The current instance for further configuration. - public static ComponentsBuilder Commands(this ComponentsBuilder componentsBuilder, params string[] globalLocalCommands) + public static ComponentsBuilder Commands(this ComponentsBuilder componentsBuilder, params IEnumerable globalLocalCommands) { - return componentsBuilder.Commands(string.Empty, globalLocalCommands); + return componentsBuilder.CommandGroups(string.Empty, globalLocalCommands); } /// @@ -44,27 +47,71 @@ public static ComponentsBuilder Commands(this ComponentsBuilder componentsBuilde /// The group name for the commands, or an empty string for no group. /// An array of command names to add as both global and local commands. /// The current instance for further configuration. - public static ComponentsBuilder Commands(this ComponentsBuilder componentsBuilder, string groupName, params string[] globalLocalCommands) + public static ComponentsBuilder CommandGroups(this ComponentsBuilder componentsBuilder, string groupName, params IEnumerable globalLocalCommands) { - if (globalLocalCommands.Length == 0) + if (globalLocalCommands is null) return componentsBuilder; - var commandEntry = componentsBuilder.DataBuilder.CreateElement("Commands"); + if (!globalLocalCommands.Any()) + return componentsBuilder; + + var autoCADCommands = new AutoCADCommands(); if (!string.IsNullOrWhiteSpace(groupName)) { - commandEntry.CreateAttribute("GroupName", groupName); + autoCADCommands.GroupName = groupName; } foreach (var globalLocalCommand in globalLocalCommands) { - if (!string.IsNullOrWhiteSpace(globalLocalCommand)) continue; + if (string.IsNullOrWhiteSpace(globalLocalCommand)) continue; - commandEntry.CreateElement("Command") - .CreateAttribute("Global", globalLocalCommand) - .CreateAttribute("Local", globalLocalCommand); + autoCADCommands.Commands.Add( + new AutoCADCommand + { + Global = globalLocalCommand, + Local = globalLocalCommand + }); } + componentsBuilder.DataBuilder.CreateElement("Commands", autoCADCommands); + return componentsBuilder; } + + /// + /// Represents a collection of AutoCAD command definitions, optionally grouped by a name. + /// + public class AutoCADCommands : ExtensibleData + { + /// + /// Gets or sets the group name for the commands. If not specified, commands are not grouped. + /// + [XmlAttribute("GroupName")] + public string GroupName { get; set; } + + /// + /// Gets or sets the list of AutoCAD command definitions. + /// + [XmlElement("Command")] + public List Commands { get; set; } = new List(); + } + + /// + /// Represents a single AutoCAD command definition with global and local names. + /// + public class AutoCADCommand : ExtensibleData + { + /// + /// Gets or sets the global name of the command. + /// + [XmlAttribute("Global")] + public string Global { get; set; } + + /// + /// Gets or sets the local name of the command. + /// + [XmlAttribute("Local")] + public string Local { get; set; } + } } diff --git a/Autodesk.PackageBuilder/Utils/AutoCADUtils.cs b/Autodesk.PackageBuilder/Utils/AutoCADUtils.cs index 6a01d23..b285fea 100644 --- a/Autodesk.PackageBuilder/Utils/AutoCADUtils.cs +++ b/Autodesk.PackageBuilder/Utils/AutoCADUtils.cs @@ -26,6 +26,24 @@ public static ApplicationPackageBuilder AutoCADApplication(this ApplicationPacka .AutodeskProduct(AutodeskProducts.AutoCAD); } + /// + /// Configures the for the specified AutoCAD version on Windows 64-bit. + /// + /// The components builder instance. + /// The AutoCAD version as a string (e.g., "24.0"). + /// The instance for chaining. + /// + /// This overload parses the version string and delegates to the overload. + /// + public static ComponentsBuilder AutoCADPlatform(this ComponentsBuilder componentsBuilder, string autoCADVersion) + { + if (Version.TryParse(autoCADVersion, out var version)) + { + return componentsBuilder.AutoCADPlatform(version); + } + throw new ArgumentException($"Invalid AutoCAD version format: {autoCADVersion}", nameof(autoCADVersion)); + } + /// /// Configures the for the specified AutoCAD version on Windows 64-bit. /// @@ -40,6 +58,27 @@ public static ComponentsBuilder AutoCADPlatform(this ComponentsBuilder component return componentsBuilder.AutoCADPlatform(Os, Platform, autoCADVersion); } + /// + /// Configures the for the specified OS, platform, and AutoCAD version. + /// + /// The components builder instance. + /// The operating system (e.g., "Win64"). + /// The platform (e.g., "AutoCAD*"). + /// The AutoCAD version as a string (e.g., "24.0"). + /// The instance for chaining. + /// Thrown if is not a valid version string. + /// + /// This overload parses the version string and delegates to the overload. + /// + public static ComponentsBuilder AutoCADPlatform(this ComponentsBuilder componentsBuilder, string os, string platform, string autoCADVersion) + { + if (Version.TryParse(autoCADVersion, out var version)) + { + return componentsBuilder.AutoCADPlatform(os, platform, version); + } + throw new ArgumentException($"Invalid AutoCAD version format: {autoCADVersion}", nameof(autoCADVersion)); + } + /// /// Configures the for the specified OS, platform, and AutoCAD version. /// @@ -57,6 +96,32 @@ public static ComponentsBuilder AutoCADPlatform(this ComponentsBuilder component return componentsBuilder.AutoCADPlatform(os, platform, autoCADVersion, autoCADVersion); } + /// + /// Configures the for a range of AutoCAD versions on Windows 64-bit. + /// + /// The components builder instance. + /// The minimum AutoCAD version as a string (e.g., "24.0"). + /// The maximum AutoCAD version as a string (e.g., "25.0"). + /// + /// If true, sets the maximum version to one less than . + /// + /// The instance for chaining. + /// + /// Thrown if is not a valid version string. + /// + /// + /// This overload parses the version strings and delegates to the overload. + /// + public static ComponentsBuilder AutoCADPlatform(this ComponentsBuilder componentsBuilder, string minVersion, string maxVersion, bool maxVersionMinusOne = false) + { + if (Version.TryParse(minVersion, out var version)) + { + Version.TryParse(maxVersion, out var versionMax); + return componentsBuilder.AutoCADPlatform(version, versionMax, maxVersionMinusOne); + } + throw new ArgumentException($"Invalid AutoCAD version format: {minVersion}", nameof(minVersion)); + } + /// /// Configures the for a range of AutoCAD versions on Windows 64-bit. /// @@ -73,6 +138,34 @@ public static ComponentsBuilder AutoCADPlatform(this ComponentsBuilder component return componentsBuilder.AutoCADPlatform(Os, Platform, minVersion, maxVersion, maxVersionMinusOne); } + /// + /// Configures the for the specified OS, platform, and AutoCAD version range. + /// + /// The components builder instance. + /// The operating system (e.g., "Win64"). + /// The platform (e.g., "AutoCAD*"). + /// The minimum AutoCAD version as a string (e.g., "24.0"). + /// The maximum AutoCAD version as a string (e.g., "25.0"). + /// + /// If true, sets the maximum version to one less than . + /// + /// The instance for chaining. + /// + /// Thrown if is not a valid version string. + /// + /// + /// This overload parses the version strings and delegates to the overload. + /// + public static ComponentsBuilder AutoCADPlatform(this ComponentsBuilder componentsBuilder, string os, string platform, string minVersion, string maxVersion, bool maxVersionMinusOne = false) + { + if (Version.TryParse(minVersion, out var version)) + { + Version.TryParse(maxVersion, out var versionMax); + return componentsBuilder.AutoCADPlatform(os, platform, version, versionMax, maxVersionMinusOne); + } + throw new ArgumentException($"Invalid AutoCAD version format: {minVersion}", nameof(minVersion)); + } + /// /// Configures the for a range of AutoCAD versions, with options for OS, platform, and version range. /// diff --git a/CHANGELOG.md b/CHANGELOG.md index 0aa4c3e..0d569c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,8 +14,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Add `DataBuilderBase` and `DataBuilderBaseExtension`. - Add `AutoCADUtils` to support `AutoCADApplication` and `AutoCADPlatform`. - Add `AutoCADExtensibleData` to support `LoadOnAppearance` and `Commands`. +- Add `AutoCADCommands` and `AutoCADCommand` in `AutoCADExtensibleData`. ### Tests - Add `DataBuild_Tests` to test `DataBuilder` +- Add `PackageContentsBuilder_AutoCAD_Tests` and `PackageContentsBuilder_Revit_Tests`. ## [1.0.6] / 2023-11-24 - 2023-12-06 ### Features From 33688f9d9664d8e4cece37e1c62aa49d5310a739 Mon Sep 17 00:00:00 2001 From: Luiz Henrique Cassettari Date: Wed, 28 May 2025 11:06:37 -0300 Subject: [PATCH 13/38] Version 1.1.0-beta.1 --- Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Build.props b/Directory.Build.props index 630c6cc..975c3cd 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,5 +1,5 @@ - 1.1.0-beta + 1.1.0-beta.1 \ No newline at end of file From 8855e28406847daa207e632895145adc90c017b4 Mon Sep 17 00:00:00 2001 From: Luiz Henrique Cassettari Date: Wed, 28 May 2025 14:23:27 -0300 Subject: [PATCH 14/38] Remove console --- .../Application/PackageContentsBuilder_AutoCAD_Tests.cs | 1 - Autodesk.PackageBuilder.Tests/Data/DataBuild_Tests.cs | 9 +++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Autodesk.PackageBuilder.Tests/Application/PackageContentsBuilder_AutoCAD_Tests.cs b/Autodesk.PackageBuilder.Tests/Application/PackageContentsBuilder_AutoCAD_Tests.cs index fc05baa..b377be3 100644 --- a/Autodesk.PackageBuilder.Tests/Application/PackageContentsBuilder_AutoCAD_Tests.cs +++ b/Autodesk.PackageBuilder.Tests/Application/PackageContentsBuilder_AutoCAD_Tests.cs @@ -12,7 +12,6 @@ public void Build_PackageBuilder_AutoCADClass() { var builder = BuilderUtils.Build(); var content = builder.ToString(); - Console.WriteLine(content); #if NET6_0 if (AutoCADPackageBuilder.Expected.Equals(content) == false) Assert.Ignore("Not equal, order not match in version net6.0 for some reason..."); diff --git a/Autodesk.PackageBuilder.Tests/Data/DataBuild_Tests.cs b/Autodesk.PackageBuilder.Tests/Data/DataBuild_Tests.cs index bb30030..3a6b9e2 100644 --- a/Autodesk.PackageBuilder.Tests/Data/DataBuild_Tests.cs +++ b/Autodesk.PackageBuilder.Tests/Data/DataBuild_Tests.cs @@ -1,6 +1,7 @@ using Autodesk.PackageBuilder.Model.Application; using Autodesk.PackageBuilder.Tests.Utils; using NUnit.Framework; +using System; using System.Xml.Serialization; namespace Autodesk.PackageBuilder.Tests.Data @@ -21,7 +22,7 @@ public void DataBuilder_CreateAttribute(string name, object value) var applicationPackageBuilder = builder.ApplicationPackage.Create(); applicationPackageBuilder.DataBuilder.CreateAttribute(name, value); - System.Console.WriteLine(builder.ToString()); + // Console.WriteLine(builder.ToString()); builder.AssertAttribute(name, value); } @@ -33,7 +34,7 @@ public void DataBuilder_CreateElement(string name, object value) var applicationPackageBuilder = builder.ApplicationPackage.Create(); applicationPackageBuilder.DataBuilder.CreateElement(name, value); - System.Console.WriteLine(builder.ToString()); + // Console.WriteLine(builder.ToString()); builder.AssertElement(name, value); } @@ -50,7 +51,7 @@ public void Build_CreateComponentEntry(int length) componentsBuilder.DataBuilder.CreateAttribute("Attribute", i); } - System.Console.WriteLine(builder.ToString()); + // Console.WriteLine(builder.ToString()); for (int i = 0; i < length; i++) { @@ -79,7 +80,7 @@ public void Build_CustomExtensibleData() }); var result = builder.ToString(); - System.Console.WriteLine(result); + // Console.WriteLine(result); Assert.AreEqual(Expected, result, $"Expected: {Expected}\nContent: {result}"); } From e2287e2dc1b8c8137a121e758f9bef8a558ca36a Mon Sep 17 00:00:00 2001 From: Luiz Henrique Cassettari Date: Fri, 30 May 2025 10:06:33 -0300 Subject: [PATCH 15/38] Replace IEnumerable to array --- .../Application/PackageContentsBuilder_AutoCAD_Tests.cs | 2 +- .../Extensible/AutoCAD/AutoCADExtensibleData.cs | 4 ++-- Directory.Build.props | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Autodesk.PackageBuilder.Tests/Application/PackageContentsBuilder_AutoCAD_Tests.cs b/Autodesk.PackageBuilder.Tests/Application/PackageContentsBuilder_AutoCAD_Tests.cs index b377be3..4d13664 100644 --- a/Autodesk.PackageBuilder.Tests/Application/PackageContentsBuilder_AutoCAD_Tests.cs +++ b/Autodesk.PackageBuilder.Tests/Application/PackageContentsBuilder_AutoCAD_Tests.cs @@ -126,7 +126,7 @@ public AutoCADPackageBuilder() .AppName("AutoCADAddin") .ModuleName(@"./Contents/2025/AutoCADAddin.dll") .LoadOnAppearance() - .Commands(commends.Skip(1)); + .Commands(commends.LastOrDefault()); } } diff --git a/Autodesk.PackageBuilder/Extensible/AutoCAD/AutoCADExtensibleData.cs b/Autodesk.PackageBuilder/Extensible/AutoCAD/AutoCADExtensibleData.cs index e7b6bc4..344bb47 100644 --- a/Autodesk.PackageBuilder/Extensible/AutoCAD/AutoCADExtensibleData.cs +++ b/Autodesk.PackageBuilder/Extensible/AutoCAD/AutoCADExtensibleData.cs @@ -35,7 +35,7 @@ public static ComponentsBuilder LoadOnAppearance(this ComponentsBuilder componen /// The instance to configure. /// An array of command names to add as both global and local commands. /// The current instance for further configuration. - public static ComponentsBuilder Commands(this ComponentsBuilder componentsBuilder, params IEnumerable globalLocalCommands) + public static ComponentsBuilder Commands(this ComponentsBuilder componentsBuilder, params string[] globalLocalCommands) { return componentsBuilder.CommandGroups(string.Empty, globalLocalCommands); } @@ -47,7 +47,7 @@ public static ComponentsBuilder Commands(this ComponentsBuilder componentsBuilde /// The group name for the commands, or an empty string for no group. /// An array of command names to add as both global and local commands. /// The current instance for further configuration. - public static ComponentsBuilder CommandGroups(this ComponentsBuilder componentsBuilder, string groupName, params IEnumerable globalLocalCommands) + public static ComponentsBuilder CommandGroups(this ComponentsBuilder componentsBuilder, string groupName, params string[] globalLocalCommands) { if (globalLocalCommands is null) return componentsBuilder; diff --git a/Directory.Build.props b/Directory.Build.props index 975c3cd..25e380c 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,5 +1,5 @@ - 1.1.0-beta.1 + 1.1.0-beta.2 \ No newline at end of file From f91587ceb45462645ddb6c4e61310a3fca283471 Mon Sep 17 00:00:00 2001 From: Luiz Henrique Cassettari Date: Fri, 30 May 2025 10:09:09 -0300 Subject: [PATCH 16/38] Update docs Os and Platform --- Autodesk.PackageBuilder/Utils/AutoCADUtils.cs | 10 ++++++++-- Autodesk.PackageBuilder/Utils/RevitUtils.cs | 10 ++++++++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/Autodesk.PackageBuilder/Utils/AutoCADUtils.cs b/Autodesk.PackageBuilder/Utils/AutoCADUtils.cs index b285fea..eed3078 100644 --- a/Autodesk.PackageBuilder/Utils/AutoCADUtils.cs +++ b/Autodesk.PackageBuilder/Utils/AutoCADUtils.cs @@ -11,8 +11,14 @@ namespace Autodesk.PackageBuilder; /// public static class AutoCADUtils { - private const string Os = "Win64"; - private const string Platform = "AutoCAD*"; // AutoCAD* - All AutoCAD-based products + /// + /// The default operating system for AutoCAD application packages (Windows 64-bit). + /// + public const string Os = "Win64"; + /// + /// The default platform string for all AutoCAD-based products ("AutoCAD*"). + /// + public const string Platform = "AutoCAD*"; // AutoCAD* - All AutoCAD-based products /// /// Configures the for an AutoCAD application package. diff --git a/Autodesk.PackageBuilder/Utils/RevitUtils.cs b/Autodesk.PackageBuilder/Utils/RevitUtils.cs index 4388df0..20c0674 100644 --- a/Autodesk.PackageBuilder/Utils/RevitUtils.cs +++ b/Autodesk.PackageBuilder/Utils/RevitUtils.cs @@ -5,8 +5,14 @@ /// public static class RevitUtils { - private const string Os = "Win64"; - private const string Platform = "Revit"; + /// + /// The default operating system value for Revit components ("Win64"). + /// + public const string Os = "Win64"; + /// + /// The default platform value for Revit components ("Revit"). + /// + public const string Platform = "Revit"; /// /// Configures the for Autodesk Revit as an application product type. From 3e4af7cf991aed4186280c0c01c9756437779f6f Mon Sep 17 00:00:00 2001 From: Luiz Henrique Cassettari Date: Fri, 30 May 2025 10:09:44 -0300 Subject: [PATCH 17/38] Version 1.1.0-beta.3 --- Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Build.props b/Directory.Build.props index 25e380c..25e1933 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,5 +1,5 @@ - 1.1.0-beta.2 + 1.1.0-beta.3 \ No newline at end of file From e148e3895dfbf5b83134d76dc6b2b4acfe493ff3 Mon Sep 17 00:00:00 2001 From: Luiz Henrique Cassettari Date: Wed, 4 Jun 2025 10:40:15 -0300 Subject: [PATCH 18/38] Add `InventorUtils` to support `InventorApplication` and `InventorPlatform`. --- .../Constants/AutodeskProducts.cs | 5 ++ .../Utils/InventorUtils.cs | 65 +++++++++++++++++++ CHANGELOG.md | 3 + Directory.Build.props | 2 +- 4 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 Autodesk.PackageBuilder/Utils/InventorUtils.cs diff --git a/Autodesk.PackageBuilder/Constants/AutodeskProducts.cs b/Autodesk.PackageBuilder/Constants/AutodeskProducts.cs index f05066c..9f56964 100644 --- a/Autodesk.PackageBuilder/Constants/AutodeskProducts.cs +++ b/Autodesk.PackageBuilder/Constants/AutodeskProducts.cs @@ -15,6 +15,11 @@ public static class AutodeskProducts /// public const string AutoCAD = "AutoCAD"; + /// + /// The product name for Autodesk Inventor. + /// + public const string Inventor = "Inventor"; + /// /// The product name for Autodesk Maya. /// diff --git a/Autodesk.PackageBuilder/Utils/InventorUtils.cs b/Autodesk.PackageBuilder/Utils/InventorUtils.cs new file mode 100644 index 0000000..67d72b9 --- /dev/null +++ b/Autodesk.PackageBuilder/Utils/InventorUtils.cs @@ -0,0 +1,65 @@ +namespace Autodesk.PackageBuilder; + +/// +/// Provides utility extension methods for configuring Inventor-specific application packages and components. +/// +/// +/// For more information, see the Inventor Developer Documentation: +/// https://help.autodesk.com/view/INVNTOR/2024/ENU/?guid=GUID-52422162-1784-4E8F-B495-CDB7BE9987AB +/// +public static class InventorUtils +{ + /// + /// The default operating system for Inventor application packages (Windows 64-bit). + /// + public const string Os = "Win64"; + + /// + /// The default platform string for all Inventor-based products ("Inventor"). + /// + public const string Platform = "Inventor"; + + /// + /// Configures the for an Inventor application package. + /// + /// The application package builder instance. + /// + /// The instance for chaining, configured for Inventor. + /// + public static ApplicationPackageBuilder InventorApplication(this ApplicationPackageBuilder applicationPackageBuilder) + { + return applicationPackageBuilder + .ProductType(ProductTypes.Application) + .AutodeskProduct(AutodeskProducts.Inventor); + } + + /// + /// Configures the for the default Inventor platform and operating system. + /// + /// The components builder instance. + /// + /// The instance for chaining, configured for Inventor's default OS and platform. + /// + public static ComponentsBuilder InventorPlatform(this ComponentsBuilder componentsBuilder) + { + return componentsBuilder + .OS(Os) + .Platform(Platform); + } + + /// + /// Configures the for a specified operating system and platform. + /// + /// The components builder instance. + /// The operating system to set. + /// The platform to set. + /// + /// The instance for chaining, configured for the specified OS and platform. + /// + public static ComponentsBuilder InventorPlatform(this ComponentsBuilder componentsBuilder, string os, string platform) + { + return componentsBuilder + .OS(os) + .Platform(platform); + } +} diff --git a/CHANGELOG.md b/CHANGELOG.md index 0d569c8..9f27296 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [1.1.0] / 2025-05-16 ### Features +- Support `AutoCAD` bundle. +- Support `Inventor` bundle. - Support custom `Element` and `Attribute`. - Add `IncludeSymbols` to support `SymbolPackageFormat`. ### PackageBuilder @@ -15,6 +17,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Add `AutoCADUtils` to support `AutoCADApplication` and `AutoCADPlatform`. - Add `AutoCADExtensibleData` to support `LoadOnAppearance` and `Commands`. - Add `AutoCADCommands` and `AutoCADCommand` in `AutoCADExtensibleData`. +- Add `InventorUtils` to support `InventorApplication` and `InventorPlatform`. ### Tests - Add `DataBuild_Tests` to test `DataBuilder` - Add `PackageContentsBuilder_AutoCAD_Tests` and `PackageContentsBuilder_Revit_Tests`. diff --git a/Directory.Build.props b/Directory.Build.props index 25e1933..437925f 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,5 +1,5 @@ - 1.1.0-beta.3 + 1.1.0-beta.4 \ No newline at end of file From 220c82f0d3e52b35463169714602e1aef2b9efbd Mon Sep 17 00:00:00 2001 From: Luiz Henrique Cassettari Date: Wed, 4 Jun 2025 11:42:12 -0300 Subject: [PATCH 19/38] Add `IInventorAddInEntryBuilder`, `InventorAddInEntryBuilder` and `InventorAddIn`. --- .../Addin/IInventorAddInEntryBuilder.cs | 20 +++ ...yBuilder.cs => IRevitAddInEntryBuilder.cs} | 6 +- .../Builder/Addin/AddInEntryBuilder.cs | 89 ---------- .../Addin/InventorAddInEntryBuilder.cs | 152 ++++++++++++++++++ .../Builder/Addin/RevitAddInEntryBuilder.cs | 89 ++++++++++ .../Builder/InventorAddInsBuilder.cs | 52 ++++++ .../Builder/RevitAddInsBuilder.cs | 6 +- .../Model/Addin/AddInApplication.cs | 58 ------- .../Model/Addin/InventorAddIn.cs | 138 ++++++++++++++++ .../{AddInModel.cs => RevitAddInData.cs} | 2 +- .../Model/Addin/RevitAddIns.cs | 2 +- CHANGELOG.md | 2 + Directory.Build.props | 2 +- 13 files changed, 462 insertions(+), 156 deletions(-) create mode 100644 Autodesk.PackageBuilder/Builder/Abstractions/Addin/IInventorAddInEntryBuilder.cs rename Autodesk.PackageBuilder/Builder/Abstractions/Addin/{IAddInEntryBuilder.cs => IRevitAddInEntryBuilder.cs} (64%) delete mode 100644 Autodesk.PackageBuilder/Builder/Addin/AddInEntryBuilder.cs create mode 100644 Autodesk.PackageBuilder/Builder/Addin/InventorAddInEntryBuilder.cs create mode 100644 Autodesk.PackageBuilder/Builder/Addin/RevitAddInEntryBuilder.cs create mode 100644 Autodesk.PackageBuilder/Builder/InventorAddInsBuilder.cs delete mode 100644 Autodesk.PackageBuilder/Model/Addin/AddInApplication.cs create mode 100644 Autodesk.PackageBuilder/Model/Addin/InventorAddIn.cs rename Autodesk.PackageBuilder/Model/Addin/{AddInModel.cs => RevitAddInData.cs} (96%) diff --git a/Autodesk.PackageBuilder/Builder/Abstractions/Addin/IInventorAddInEntryBuilder.cs b/Autodesk.PackageBuilder/Builder/Abstractions/Addin/IInventorAddInEntryBuilder.cs new file mode 100644 index 0000000..374aa37 --- /dev/null +++ b/Autodesk.PackageBuilder/Builder/Abstractions/Addin/IInventorAddInEntryBuilder.cs @@ -0,0 +1,20 @@ +namespace Autodesk.PackageBuilder; + +/// +/// Defines a builder interface for constructing instances +/// for Autodesk Inventor add-in packaging. +/// +public interface IInventorAddInEntryBuilder +{ + /// + /// Creates a new instance with the specified add-in type. + /// + /// + /// The type of the add-in to create (e.g., "Standard" or "Application"). + /// Defaults to "Standard" if not specified. + /// + /// + /// An instance for further configuration. + /// + InventorAddInEntryBuilder Create(string type = "Standard"); +} \ No newline at end of file diff --git a/Autodesk.PackageBuilder/Builder/Abstractions/Addin/IAddInEntryBuilder.cs b/Autodesk.PackageBuilder/Builder/Abstractions/Addin/IRevitAddInEntryBuilder.cs similarity index 64% rename from Autodesk.PackageBuilder/Builder/Abstractions/Addin/IAddInEntryBuilder.cs rename to Autodesk.PackageBuilder/Builder/Abstractions/Addin/IRevitAddInEntryBuilder.cs index 6bb15c3..728fda8 100644 --- a/Autodesk.PackageBuilder/Builder/Abstractions/Addin/IAddInEntryBuilder.cs +++ b/Autodesk.PackageBuilder/Builder/Abstractions/Addin/IRevitAddInEntryBuilder.cs @@ -3,15 +3,15 @@ /// /// Defines a builder interface for creating add-in entry configurations. /// - public interface IAddInEntryBuilder + public interface IRevitAddInEntryBuilder { /// /// Creates a new add-in entry with the specified type. /// /// The type of the add-in entry. Defaults to "Application". /// - /// An instance for further configuration of the add-in entry. + /// An instance for further configuration of the add-in entry. /// - AddInEntryBuilder CreateEntry(string type = "Application"); + RevitAddInEntryBuilder CreateEntry(string type = "Application"); } } \ No newline at end of file diff --git a/Autodesk.PackageBuilder/Builder/Addin/AddInEntryBuilder.cs b/Autodesk.PackageBuilder/Builder/Addin/AddInEntryBuilder.cs deleted file mode 100644 index 2bceabd..0000000 --- a/Autodesk.PackageBuilder/Builder/Addin/AddInEntryBuilder.cs +++ /dev/null @@ -1,89 +0,0 @@ -namespace Autodesk.PackageBuilder -{ - using Model.Addin; - using System.Collections.Generic; - /// - /// Provides a builder for creating and configuring entries. - /// - public class AddInEntryBuilder : ListBuilderBase, IAddInEntryBuilder - { - /// - /// Initializes a new instance of the class with the specified list of objects. - /// - /// The list of objects to initialize the builder with. - public AddInEntryBuilder(List models) - { - SetDataInternal(models); - } - - /// - /// Creates a new add-in entry and sets its type. - /// - /// The type of the add-in entry (e.g., "Application"). - /// The current instance for method chaining. - public AddInEntryBuilder CreateEntry(string type) - { - CreateEntryInternal(); - Type(type); - return this; - } - - /// - /// Sets the property for the current entry. - /// - /// The type value to set. - /// The current instance for method chaining. - private AddInEntryBuilder Type(string value) => SetPropertyValue(value); - - /// - /// Sets the property for the current entry. - /// - /// The name value to set. - /// The current instance for method chaining. - public AddInEntryBuilder Name(string value) => SetPropertyValue(value); - - /// - /// Sets the property for the current entry. - /// - /// The assembly value to set. - /// The current instance for method chaining. - public AddInEntryBuilder Assembly(string value) => SetPropertyValue(value); - - /// - /// Sets the property for the current entry. - /// - /// The add-in ID value to set. - /// The current instance for method chaining. - public AddInEntryBuilder AddInId(string value) => SetPropertyValue(value); - - /// - /// Sets the property for the current entry. - /// - /// The fully qualified class name to set. - /// The current instance for method chaining. - public AddInEntryBuilder FullClassName(string value) => SetPropertyValue(value); - - /// - /// Sets the property for the current entry. - /// - /// The vendor ID value to set. - /// The current instance for method chaining. - public AddInEntryBuilder VendorId(string value) => SetPropertyValue(value); - - /// - /// Sets the property for the current entry. - /// - /// The vendor description value to set. - /// The current instance for method chaining. - public AddInEntryBuilder VendorDescription(string value) => SetPropertyValue(value); - - /// - /// (Obsolete) Sets the AllowLoadingIntoExistingSession property for the current entry. - /// This method is obsolete and will be removed in a future version. - /// - /// A value indicating whether loading into an existing session is allowed. - /// The current instance for method chaining. - [System.Obsolete("This method does not have a Property 'AllowLoadingIntoExistingSession' in class AddInModel, will be removed in a future version.")] - internal AddInEntryBuilder AllowLoadingIntoExistingSession(bool value) => SetPropertyValue(value); - } -} \ No newline at end of file diff --git a/Autodesk.PackageBuilder/Builder/Addin/InventorAddInEntryBuilder.cs b/Autodesk.PackageBuilder/Builder/Addin/InventorAddInEntryBuilder.cs new file mode 100644 index 0000000..afda84b --- /dev/null +++ b/Autodesk.PackageBuilder/Builder/Addin/InventorAddInEntryBuilder.cs @@ -0,0 +1,152 @@ +namespace Autodesk.PackageBuilder; + +using Model.Addin; +using System; + +/// +/// Provides a builder for constructing entries for Autodesk Inventor packaging. +/// +public class InventorAddInEntryBuilder : SingleBuilderBase, IInventorAddInEntryBuilder +{ + /// + /// Initializes a new instance of the class with the specified model. + /// + /// The model to initialize the builder with. + public InventorAddInEntryBuilder(InventorAddIn model) + { + SetDataInternal(model); + } + + /// + /// Sets the type of the add-in and returns the builder instance. + /// + /// The type of the add-in (e.g., "Standard" or "Application"). + /// The current instance. + public InventorAddInEntryBuilder Create(string type) + { + return Type(type); + } + + /// + /// Converts a to a string in "B" format and upper case. + /// + /// The to convert. + /// The string representation of the GUID in "B" format and upper case. + private string GuidToString(Guid guid) + { + return guid.ToString("B").ToUpperInvariant(); + } + + /// + /// Sets the type of the add-in and returns the builder instance. + /// + /// The type value to set. + /// The current instance. + private InventorAddInEntryBuilder Type(string value) => SetPropertyValue(value); + + /// + /// Sets the COM class ID (GUID) of the add-in and returns the builder instance. + /// + /// The class ID as a string. + /// The current instance. + public InventorAddInEntryBuilder ClassId(string value) => SetPropertyValue(value); + + /// + /// Sets the COM class ID (GUID) of the add-in and returns the builder instance. + /// + /// The class ID as a . + /// The current instance. + public InventorAddInEntryBuilder ClassId(Guid value) => ClassId(GuidToString(value)); + + /// + /// Sets the client ID (GUID) of the add-in and returns the builder instance. + /// + /// The client ID as a string. + /// The current instance. + public InventorAddInEntryBuilder ClientId(string value) => SetPropertyValue(value); + + /// + /// Sets the client ID (GUID) of the add-in and returns the builder instance. + /// + /// The client ID as a . + /// The current instance. + public InventorAddInEntryBuilder ClientId(Guid value) => ClientId(GuidToString(value)); + + /// + /// Sets the display name of the add-in and returns the builder instance. + /// + /// The display name to set. + /// The current instance. + public InventorAddInEntryBuilder DisplayName(string value) => SetPropertyValue(value); + + /// + /// Sets the description of the add-in and returns the builder instance. + /// + /// The description to set. + /// The current instance. + public InventorAddInEntryBuilder Description(string value) => SetPropertyValue(value); + + /// + /// Sets the assembly path of the add-in and returns the builder instance. + /// + /// The assembly path to set. + /// The current instance. + public InventorAddInEntryBuilder Assembly(string value) => SetPropertyValue(value); + + /// + /// Sets whether the add-in should load automatically and returns the builder instance. + /// + /// 1 to load automatically, 0 otherwise. + /// The current instance. + public InventorAddInEntryBuilder LoadAutomatically(int? value) => SetPropertyValue(value); + + /// + /// Sets the load behavior of the add-in and returns the builder instance. + /// + /// The load behavior value to set. + /// The current instance. + public InventorAddInEntryBuilder LoadBehavior(int? value) => SetPropertyValue(value); + + /// + /// Sets whether the add-in can be unloaded by the user and returns the builder instance. + /// + /// 1 if user can unload, 0 otherwise. + /// The current instance. + public InventorAddInEntryBuilder UserUnloadable(int? value) => SetPropertyValue(value); + + /// + /// Sets whether the add-in is hidden in the Add-in Manager and returns the builder instance. + /// + /// 1 if hidden, 0 otherwise. + /// The current instance. + public InventorAddInEntryBuilder Hidden(int? value) => SetPropertyValue(value); + + /// + /// Sets the exact Inventor version this add-in supports and returns the builder instance. + /// + /// The version string to set. + /// The current instance. + public InventorAddInEntryBuilder SupportedSoftwareVersionEqualTo(string value) => SetPropertyValue(value); + + /// + /// Sets the minimum Inventor version (exclusive) this add-in supports and returns the builder instance. + /// + /// The version string to set. + /// The current instance. + public InventorAddInEntryBuilder SupportedSoftwareVersionGreaterThan(string value) => SetPropertyValue(value); + + /// + /// Sets the maximum Inventor version (exclusive) this add-in supports and returns the builder instance. + /// + /// The version string to set. + /// The current instance. + public InventorAddInEntryBuilder SupportedSoftwareVersionLessThan(string value) => SetPropertyValue(value); + + /// + /// Sets the Inventor version this add-in does not support and returns the builder instance. + /// + /// The version string to set. + /// The current instance. + public InventorAddInEntryBuilder SupportedSoftwareVersionNotEqualTo(string value) => SetPropertyValue(value); + +} \ No newline at end of file diff --git a/Autodesk.PackageBuilder/Builder/Addin/RevitAddInEntryBuilder.cs b/Autodesk.PackageBuilder/Builder/Addin/RevitAddInEntryBuilder.cs new file mode 100644 index 0000000..d8c6a44 --- /dev/null +++ b/Autodesk.PackageBuilder/Builder/Addin/RevitAddInEntryBuilder.cs @@ -0,0 +1,89 @@ +namespace Autodesk.PackageBuilder +{ + using Model.Addin; + using System.Collections.Generic; + /// + /// Provides a builder for creating and configuring entries. + /// + public class RevitAddInEntryBuilder : ListBuilderBase, IRevitAddInEntryBuilder + { + /// + /// Initializes a new instance of the class with the specified list of objects. + /// + /// The list of objects to initialize the builder with. + public RevitAddInEntryBuilder(List models) + { + SetDataInternal(models); + } + + /// + /// Creates a new add-in entry and sets its type. + /// + /// The type of the add-in entry (e.g., "Application"). + /// The current instance for method chaining. + public RevitAddInEntryBuilder CreateEntry(string type) + { + CreateEntryInternal(); + Type(type); + return this; + } + + /// + /// Sets the property for the current entry. + /// + /// The type value to set. + /// The current instance for method chaining. + private RevitAddInEntryBuilder Type(string value) => SetPropertyValue(value); + + /// + /// Sets the property for the current entry. + /// + /// The name value to set. + /// The current instance for method chaining. + public RevitAddInEntryBuilder Name(string value) => SetPropertyValue(value); + + /// + /// Sets the property for the current entry. + /// + /// The assembly value to set. + /// The current instance for method chaining. + public RevitAddInEntryBuilder Assembly(string value) => SetPropertyValue(value); + + /// + /// Sets the property for the current entry. + /// + /// The add-in ID value to set. + /// The current instance for method chaining. + public RevitAddInEntryBuilder AddInId(string value) => SetPropertyValue(value); + + /// + /// Sets the property for the current entry. + /// + /// The fully qualified class name to set. + /// The current instance for method chaining. + public RevitAddInEntryBuilder FullClassName(string value) => SetPropertyValue(value); + + /// + /// Sets the property for the current entry. + /// + /// The vendor ID value to set. + /// The current instance for method chaining. + public RevitAddInEntryBuilder VendorId(string value) => SetPropertyValue(value); + + /// + /// Sets the property for the current entry. + /// + /// The vendor description value to set. + /// The current instance for method chaining. + public RevitAddInEntryBuilder VendorDescription(string value) => SetPropertyValue(value); + + /// + /// (Obsolete) Sets the AllowLoadingIntoExistingSession property for the current entry. + /// This method is obsolete and will be removed in a future version. + /// + /// A value indicating whether loading into an existing session is allowed. + /// The current instance for method chaining. + [System.Obsolete("This method does not have a Property 'AllowLoadingIntoExistingSession' in class AddInModel, will be removed in a future version.")] + internal RevitAddInEntryBuilder AllowLoadingIntoExistingSession(bool value) => SetPropertyValue(value); + } +} \ No newline at end of file diff --git a/Autodesk.PackageBuilder/Builder/InventorAddInsBuilder.cs b/Autodesk.PackageBuilder/Builder/InventorAddInsBuilder.cs new file mode 100644 index 0000000..8d48cee --- /dev/null +++ b/Autodesk.PackageBuilder/Builder/InventorAddInsBuilder.cs @@ -0,0 +1,52 @@ +namespace Autodesk.PackageBuilder; + +using Model.Addin; + +/// +/// Provides a builder for creating and serializing Autodesk Inventor Add-In definitions. +/// +public class InventorAddInsBuilder : IBuilder +{ + /// + /// The Inventor Add-In model instance being built. + /// + private readonly InventorAddIn inventorAddIns; + + /// + /// The builder for configuring Inventor Add-In entry properties. + /// + private readonly InventorAddInEntryBuilder _inventorAddInsEntryBuilder; + + /// + /// Gets the entry builder for configuring the Inventor Add-In. + /// + public IInventorAddInEntryBuilder AddIn => _inventorAddInsEntryBuilder; + + /// + /// Initializes a new instance of the class. + /// + public InventorAddInsBuilder() + { + inventorAddIns = new InventorAddIn(); + _inventorAddInsEntryBuilder = new InventorAddInEntryBuilder(inventorAddIns); + } + + /// + /// Serializes the Inventor Add-In definition to a file at the specified path with a ".addin" extension. + /// + /// The file path where the add-in definition will be saved. + /// The full path to the serialized add-in file. + public string Build(string path) + { + return inventorAddIns.SerializeFile(path, ".addin"); + } + + /// + /// Serializes the Inventor Add-In definition to an XML string. + /// + /// The XML representation of the add-in definition. + public override string ToString() + { + return inventorAddIns.SerializeObject(); + } +} \ No newline at end of file diff --git a/Autodesk.PackageBuilder/Builder/RevitAddInsBuilder.cs b/Autodesk.PackageBuilder/Builder/RevitAddInsBuilder.cs index 45dc4dc..0172000 100644 --- a/Autodesk.PackageBuilder/Builder/RevitAddInsBuilder.cs +++ b/Autodesk.PackageBuilder/Builder/RevitAddInsBuilder.cs @@ -19,12 +19,12 @@ public class RevitAddInsBuilder : IBuilder /// /// The builder for configuring individual add-in entries. /// - private readonly AddInEntryBuilder _addInEntryBuilder; + private readonly RevitAddInEntryBuilder _addInEntryBuilder; /// /// Gets the builder for creating and configuring add-in entries. /// - public IAddInEntryBuilder AddIn => _addInEntryBuilder; + public IRevitAddInEntryBuilder AddIn => _addInEntryBuilder; /// /// Initializes a new instance of the class. @@ -33,7 +33,7 @@ public RevitAddInsBuilder() { revitAddIns = new RevitAddIns(); _revitAddInsEntryBuilder = new RevitAddInsEntryBuilder(revitAddIns); - _addInEntryBuilder = new AddInEntryBuilder(revitAddIns.AddIn); + _addInEntryBuilder = new RevitAddInEntryBuilder(revitAddIns.AddIn); } /// diff --git a/Autodesk.PackageBuilder/Model/Addin/AddInApplication.cs b/Autodesk.PackageBuilder/Model/Addin/AddInApplication.cs deleted file mode 100644 index a3f44cd..0000000 --- a/Autodesk.PackageBuilder/Model/Addin/AddInApplication.cs +++ /dev/null @@ -1,58 +0,0 @@ -namespace Autodesk.PackageBuilder.Model.Addin -{ - using System.Xml; - using System.Xml.Serialization; - /// - /// Represents an add-in application definition for Autodesk products. - /// - public class AddInApplication : ExtensibleData - { - /// - /// Gets or sets the type of the add-in application. - /// - [XmlAttribute] - public string Type { get; set; } - - /// - /// Gets or sets the display name of the add-in application. - /// - [XmlElement] - public string Name { get; set; } - - /// - /// Gets or sets the assembly file name or path for the add-in application. - /// - [XmlElement] - public string Assembly { get; set; } - - /// - /// Gets or sets the unique identifier for the add-in application. - /// - [XmlElement] - public string AddInId { get; set; } - - /// - /// Gets or sets the fully qualified class name that implements the add-in application. - /// - [XmlElement] - public string FullClassName { get; set; } - - /// - /// Gets or sets the vendor identifier for the add-in application. - /// - [XmlElement] - public string VendorId { get; set; } - - /// - /// Gets or sets the vendor description for the add-in application. - /// - [XmlElement] - public string VendorDescription { get; set; } - - /// - /// Gets or sets a value indicating whether the add-in can be loaded into an existing session. - /// - [XmlElement] - public bool AllowLoadingIntoExistingSession { get; set; } = true; - } -} diff --git a/Autodesk.PackageBuilder/Model/Addin/InventorAddIn.cs b/Autodesk.PackageBuilder/Model/Addin/InventorAddIn.cs new file mode 100644 index 0000000..da707f1 --- /dev/null +++ b/Autodesk.PackageBuilder/Model/Addin/InventorAddIn.cs @@ -0,0 +1,138 @@ +namespace Autodesk.PackageBuilder.Model.Addin; + +using System; +using System.Xml; +using System.Xml.Serialization; + +/// +/// Represents an Inventor Add-In definition for Autodesk Inventor packaging. +/// +/// +/// For more information, see the Inventor Developer Documentation: +/// https://help.autodesk.com/view/INVNTOR/2024/ENU/?guid=GUID-52422162-1784-4E8F-B495-CDB7BE9987AB +/// +[Serializable] +[XmlRoot("AddIn")] +public class InventorAddIn : ExtensibleData, IPackageSerializable +{ + /// + /// Gets or sets the type of the add-in. Typically "Standard" or "Application". + /// + [XmlAttribute] + public string Type { get; set; } + + /// + /// Gets or sets the COM class ID (GUID) of the add-in. + /// + [XmlElement] + public string ClassId { get; set; } + + /// + /// Gets or sets the client ID (GUID) of the add-in. + /// + [XmlElement] + public string ClientId { get; set; } + + /// + /// Gets or sets the display name of the add-in as shown in Inventor. + /// + [XmlElement] + public string DisplayName { get; set; } + + /// + /// Gets or sets the description of the add-in. + /// + [XmlElement] + public string Description { get; set; } + + /// + /// Gets or sets the path to the add-in assembly (DLL). + /// + [XmlElement] + public string Assembly { get; set; } + + /// + /// (Optional) Specifies whether the add-in should be allowed to load automatically as per the load behaviors defined by the add-in. + /// + /// + /// + /// This option can be specified using one of the following values: + /// 0 - The add-in needs to be manually loaded using the add-in manager. + /// 1 - The add-in can be loaded automatically as per the load behaviors defined by the add-in. + /// Assumed to be 1 if this value is not specified. (add-in loads automatically) + /// + /// + [XmlElement] + public int? LoadAutomatically { get; set; } + + /// + /// (Optional) Specifies when the add-in should be loaded in Inventor. This is important for better startup performance. + /// + /// + /// + /// This option can be specified using one of the following values: + /// 0 - Load immediately on startup (not recommended) + /// 1 - Load when any document is opened + /// 1 - Load when a part document is opened (same as previous) + /// 2 - Load when an assembly document is opened + /// 3 - Load when a presentation document is opened + /// 4 - Load when a drawing document is opened + /// 10 - Load only on demand, either through the API or using the Add-In Manager. + /// Assumed to be 0 if this value is not specified. (add-in loads immediately on startup) + /// + /// + [XmlElement] + public int? LoadBehavior { get; set; } + + /// + /// (Optional) Specifies whether the add-in can be unloaded by the user using the Add-In Manager. + /// + /// + /// + /// This option can be specified using one of the following values: + /// 0 - The add-in cannot be unloaded by the user. + /// 1 - The add-in can be unloaded by the user. + /// Assumed to be 1 if this value is not specified. (add-in is unloadable by user) + /// + /// + [XmlElement] + public int? UserUnloadable { get; set; } + + /// + /// Specifies whether the add-in should be hidden in the Add-in Manager’s list of add-ins. + /// + /// + /// + /// This option can be specified using one of the following values: + /// 0 - The add-in is visible in the Add-in Manager. + /// 1 - The add-in is hidden in the Add-in Manager. + /// Assumed to be 0 if this value is not specified. (add-in is visible) + /// + /// + [XmlElement] + public int? Hidden { get; set; } + + /// + /// Gets or sets the exact Inventor version this add-in supports. + /// + [XmlElement] + public string SupportedSoftwareVersionEqualTo { get; set; } + + /// + /// Gets or sets the minimum Inventor version (exclusive) this add-in supports. + /// + [XmlElement] + public string SupportedSoftwareVersionGreaterThan { get; set; } + + /// + /// Gets or sets the maximum Inventor version (exclusive) this add-in supports. + /// + [XmlElement] + public string SupportedSoftwareVersionLessThan { get; set; } + + /// + /// Gets or sets the Inventor version this add-in does not support. + /// + [XmlElement] + public string SupportedSoftwareVersionNotEqualTo { get; set; } +} \ No newline at end of file diff --git a/Autodesk.PackageBuilder/Model/Addin/AddInModel.cs b/Autodesk.PackageBuilder/Model/Addin/RevitAddInData.cs similarity index 96% rename from Autodesk.PackageBuilder/Model/Addin/AddInModel.cs rename to Autodesk.PackageBuilder/Model/Addin/RevitAddInData.cs index fb8692c..1207cfa 100644 --- a/Autodesk.PackageBuilder/Model/Addin/AddInModel.cs +++ b/Autodesk.PackageBuilder/Model/Addin/RevitAddInData.cs @@ -5,7 +5,7 @@ /// /// Represents an add-in model for Autodesk Package Builder, containing metadata for an add-in. /// - public class AddInModel : ExtensibleData + public class RevitAddInData : ExtensibleData { /// /// Gets or sets the type of the add-in. diff --git a/Autodesk.PackageBuilder/Model/Addin/RevitAddIns.cs b/Autodesk.PackageBuilder/Model/Addin/RevitAddIns.cs index 337abfa..a1e11f8 100644 --- a/Autodesk.PackageBuilder/Model/Addin/RevitAddIns.cs +++ b/Autodesk.PackageBuilder/Model/Addin/RevitAddIns.cs @@ -14,6 +14,6 @@ public class RevitAddIns : ExtensibleData, IPackageSerializable /// Gets or sets the list of Revit add-in models. /// [XmlElement] - public List AddIn { get; set; } = new List(); + public List AddIn { get; set; } = new List(); } } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 9f27296..18c0749 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Add `AutoCADExtensibleData` to support `LoadOnAppearance` and `Commands`. - Add `AutoCADCommands` and `AutoCADCommand` in `AutoCADExtensibleData`. - Add `InventorUtils` to support `InventorApplication` and `InventorPlatform`. +- Rename `AddInEntryBuilder` to `RevitAddInEntryBuilder`. +- Add `IInventorAddInEntryBuilder`, `InventorAddInEntryBuilder` and `InventorAddIn`. ### Tests - Add `DataBuild_Tests` to test `DataBuilder` - Add `PackageContentsBuilder_AutoCAD_Tests` and `PackageContentsBuilder_Revit_Tests`. diff --git a/Directory.Build.props b/Directory.Build.props index 437925f..95d7f72 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,5 +1,5 @@ - 1.1.0-beta.4 + 1.1.0-beta.10 \ No newline at end of file From ab6af2aed6712e7c336883dcada4eedf60d73b04 Mon Sep 17 00:00:00 2001 From: Luiz Henrique Cassettari Date: Wed, 4 Jun 2025 11:59:42 -0300 Subject: [PATCH 20/38] Add `InventorAddInsBuilder_Tests` to test `InventorAddInEntryBuilder` --- .../Addin/InventorAddInsBuilder_Tests.cs | 129 ++++++++++++++++++ .../Utils/AssertBuilderUtils.cs | 12 ++ CHANGELOG.md | 1 + 3 files changed, 142 insertions(+) create mode 100644 Autodesk.PackageBuilder.Tests/Addin/InventorAddInsBuilder_Tests.cs diff --git a/Autodesk.PackageBuilder.Tests/Addin/InventorAddInsBuilder_Tests.cs b/Autodesk.PackageBuilder.Tests/Addin/InventorAddInsBuilder_Tests.cs new file mode 100644 index 0000000..7481d00 --- /dev/null +++ b/Autodesk.PackageBuilder.Tests/Addin/InventorAddInsBuilder_Tests.cs @@ -0,0 +1,129 @@ +using Autodesk.PackageBuilder.Tests.Utils; +using NUnit.Framework; +using System; + +namespace Autodesk.PackageBuilder.Tests.Addin +{ + public class InventorAddInsBuilder_Tests + { + InventorAddInsBuilder builder; + [SetUp] + public void Setup() + { + builder = BuilderUtils.Build(); + } + + [Test] + public void Build_InventorAddIn() + { + builder.AssertElement("AddIn"); + } + + [TestCase("Standard")] + [TestCase("NotStandard")] + public void Build_CreateEntry(string type) + { + builder.AddIn.Create(type); + builder.AssertElementAttribute("AddIn", "Type", type); + } + + [Test] + public void Build_CreateEntry_Empty() + { + string type = "Standard"; + builder.AddIn.Create(); + builder.AssertElementAttribute("AddIn", "Type", type); + } + + [TestCase("Value")] + [TestCase("PropertyValue")] + public void Build_CreateEntry_AddInId(string value) + { + builder.AddIn.Create() + .ClassId(value) + .ClientId(value) + .DisplayName(value) + .Description(value) + .Assembly(value); + + builder.AssertElement("ClassId", value); + builder.AssertElement("ClientId", value); + builder.AssertElement("DisplayName", value); + builder.AssertElement("Description", value); + builder.AssertElement("Assembly", value); + + builder.AssertNotElement("LoadAutomatically"); + builder.AssertNotElement("LoadBehavior"); + builder.AssertNotElement("UserUnloadable"); + builder.AssertNotElement("Hidden"); + } + + [TestCase("Value", 0)] + [TestCase("PropertyValue", 1)] + public void Build_CreateEntry_AddInId_Load(string value, int i) + { + builder.AddIn.Create() + .ClassId(value) + .ClientId(value) + .DisplayName(value) + .Description(value) + .Assembly(value) + .LoadAutomatically(i) + .LoadBehavior(i) + .UserUnloadable(i) + .Hidden(i); + + builder.AssertElement("ClassId", value); + builder.AssertElement("ClientId", value); + builder.AssertElement("DisplayName", value); + builder.AssertElement("Description", value); + builder.AssertElement("Assembly", value); + + builder.AssertElement("LoadAutomatically", i); + builder.AssertElement("LoadBehavior", i); + builder.AssertElement("UserUnloadable", i); + builder.AssertElement("Hidden", i); + } + + [Test] + public void Build_InventorAddIns_DemoClass() + { + var builder = BuilderUtils.Build(); + var content = builder.ToString(); + Console.WriteLine(builder.ToString()); + Assert.AreEqual(DemoAddinBuilder.Expected, content, $"Expected: {DemoAddinBuilder.Expected}\nContent: {content}"); + } + + public class DemoAddinBuilder : InventorAddInsBuilder + { + public static string Expected => """" + + + {11111111-2222-3333-4444-555555555555} + {11111111-2222-3333-4444-555555555555} + InventorAddIn + InventorAddIn + InventorAddIn.dll + 0 + 0 + 24.. + 29.. + + """"; + public DemoAddinBuilder() + { + var classId = new Guid("11111111-2222-3333-4444-555555555555"); + AddIn.Create() + .ClassId(classId) + .ClientId(classId) + .DisplayName("InventorAddIn") + .Description("InventorAddIn") + .Assembly("InventorAddIn.dll") + .LoadBehavior(0) + .UserUnloadable(0) + .SupportedSoftwareVersionGreaterThan("24..") + .SupportedSoftwareVersionLessThan("29.."); + } + } + } +} \ No newline at end of file diff --git a/Autodesk.PackageBuilder.Tests/Utils/AssertBuilderUtils.cs b/Autodesk.PackageBuilder.Tests/Utils/AssertBuilderUtils.cs index 0171145..67bdde6 100644 --- a/Autodesk.PackageBuilder.Tests/Utils/AssertBuilderUtils.cs +++ b/Autodesk.PackageBuilder.Tests/Utils/AssertBuilderUtils.cs @@ -30,6 +30,18 @@ public static void AssertElement(this IBuilder builder, string element, object v Assert.IsTrue(content.Contains(elementValue), $"The string '{elementValue}' is not found in '{content}'"); } + /// + /// Asserts that the specified is not present in the builder's content. + /// + /// The builder instance to check. + /// The name of the element to verify absence of. + public static void AssertNotElement(this IBuilder builder, string element) + { + var content = builder.ToString(); + var elementValue = ElementStart(element); + Assert.IsFalse(content.Contains(elementValue), $"The string '{elementValue}' is found in '{content}'"); + } + /// /// Assert with '=""'. /// diff --git a/CHANGELOG.md b/CHANGELOG.md index 18c0749..c160136 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ### Tests - Add `DataBuild_Tests` to test `DataBuilder` - Add `PackageContentsBuilder_AutoCAD_Tests` and `PackageContentsBuilder_Revit_Tests`. +- Add `InventorAddInsBuilder_Tests` to test `InventorAddInEntryBuilder`. ## [1.0.6] / 2023-11-24 - 2023-12-06 ### Features From 84bfcfb23a1b1b445fc83d7afbc7e792ee50ec7b Mon Sep 17 00:00:00 2001 From: Luiz Henrique Cassettari Date: Wed, 4 Jun 2025 12:51:18 -0300 Subject: [PATCH 21/38] Update `InventorUtils` to have `SupportedSoftwareVersion` extension method. --- .../Addin/InventorAddInsBuilder_Tests.cs | 47 +++++++- .../Utils/InventorUtils.cs | 111 +++++++++++++++++- CHANGELOG.md | 1 + 3 files changed, 154 insertions(+), 5 deletions(-) diff --git a/Autodesk.PackageBuilder.Tests/Addin/InventorAddInsBuilder_Tests.cs b/Autodesk.PackageBuilder.Tests/Addin/InventorAddInsBuilder_Tests.cs index 7481d00..2f67dec 100644 --- a/Autodesk.PackageBuilder.Tests/Addin/InventorAddInsBuilder_Tests.cs +++ b/Autodesk.PackageBuilder.Tests/Addin/InventorAddInsBuilder_Tests.cs @@ -21,14 +21,14 @@ public void Build_InventorAddIn() [TestCase("Standard")] [TestCase("NotStandard")] - public void Build_CreateEntry(string type) + public void Build_Create(string type) { builder.AddIn.Create(type); builder.AssertElementAttribute("AddIn", "Type", type); } [Test] - public void Build_CreateEntry_Empty() + public void Build_Create_Empty() { string type = "Standard"; builder.AddIn.Create(); @@ -37,7 +37,7 @@ public void Build_CreateEntry_Empty() [TestCase("Value")] [TestCase("PropertyValue")] - public void Build_CreateEntry_AddInId(string value) + public void Build_Create_AddInId(string value) { builder.AddIn.Create() .ClassId(value) @@ -60,7 +60,7 @@ public void Build_CreateEntry_AddInId(string value) [TestCase("Value", 0)] [TestCase("PropertyValue", 1)] - public void Build_CreateEntry_AddInId_Load(string value, int i) + public void Build_Create_AddInId_Load(string value, int i) { builder.AddIn.Create() .ClassId(value) @@ -85,6 +85,45 @@ public void Build_CreateEntry_AddInId_Load(string value, int i) builder.AssertElement("Hidden", i); } + [TestCase(28, "28..")] + [TestCase(29, "29..")] + public void Build_Create_AddInId_SupportedSoftwareVersionEqualTo(int version, string expected) + { + builder.AddIn.Create() + .SupportedSoftwareVersion(version); + + builder.AssertElement("SupportedSoftwareVersionEqualTo", expected); + builder.AssertNotElement("SupportedSoftwareVersionGreaterThan"); + builder.AssertNotElement("SupportedSoftwareVersionLessThan"); + } + + [TestCase(25, "24..")] // Inventor 2021+ + [TestCase(28, "27..")] // Inventor 2024+ + [TestCase(29, "28..")] // Inventor 2025+ + public void Build_Create_AddInId_SupportedSoftwareVersionGreaterThan(int version, string expected) + { + builder.AddIn.Create() + .SupportedSoftwareVersion(version, 0); + + builder.AssertElement("SupportedSoftwareVersionGreaterThan", expected); + builder.AssertNotElement("SupportedSoftwareVersionLessThan"); + builder.AssertNotElement("SupportedSoftwareVersionEqualTo"); + } + + [TestCase(25, "24..", 28, "29..")] // Inventor 2021+ to 2024- + [TestCase(25, "24..", 28, "28..", true)] // Inventor 2021+ to 2024- (not include 2024) + [TestCase(29, "28..", 30, "31..")] // Inventor 2025+ to 2026- + [TestCase(29, "28..", 30, "30..", true)] // Inventor 2025+ to 2026- (not include 2026) + public void Build_Create_AddInId_SupportedSoftwareVersionGreaterAndLessThan(int minVersion, string minExpected, int maxVersion, string maxExpected, bool maxVersionMinusOne = false) + { + builder.AddIn.Create() + .SupportedSoftwareVersion(minVersion, maxVersion, maxVersionMinusOne); + + builder.AssertElement("SupportedSoftwareVersionGreaterThan", minExpected); + builder.AssertElement("SupportedSoftwareVersionLessThan", maxExpected); + builder.AssertNotElement("SupportedSoftwareVersionEqualTo"); + } + [Test] public void Build_InventorAddIns_DemoClass() { diff --git a/Autodesk.PackageBuilder/Utils/InventorUtils.cs b/Autodesk.PackageBuilder/Utils/InventorUtils.cs index 67d72b9..a9e9191 100644 --- a/Autodesk.PackageBuilder/Utils/InventorUtils.cs +++ b/Autodesk.PackageBuilder/Utils/InventorUtils.cs @@ -1,4 +1,6 @@ -namespace Autodesk.PackageBuilder; +using System; + +namespace Autodesk.PackageBuilder; /// /// Provides utility extension methods for configuring Inventor-specific application packages and components. @@ -62,4 +64,111 @@ public static ComponentsBuilder InventorPlatform(this ComponentsBuilder componen .OS(os) .Platform(platform); } + + /// + /// Configures the supported Inventor software version for the add-in entry builder using an integer major version. + /// + /// The instance to configure. + /// The major version of Inventor to support. + /// + /// The instance for chaining, configured with the specified supported software version. + /// + public static InventorAddInEntryBuilder SupportedSoftwareVersion(this InventorAddInEntryBuilder builder, int version) + { + return builder.SupportedSoftwareVersion(new Version(version, 0)); + } + + /// + /// Configures the supported Inventor software version for the add-in entry builder using a object. + /// + /// The instance to configure. + /// The of Inventor to support. + /// + /// The instance for chaining, configured with the specified supported software version. + /// + public static InventorAddInEntryBuilder SupportedSoftwareVersion(this InventorAddInEntryBuilder builder, Version version) + { + return builder.SupportedSoftwareVersion(version, version); + } + + /// + /// Configures the supported Inventor software version range for the add-in entry builder using integer major versions. + /// + /// The instance to configure. + /// The minimum supported major version (inclusive if equal to , otherwise exclusive). + /// + /// The maximum supported major version (exclusive by default, or inclusive if is true). + /// + /// + /// If true, the maximum version is treated as inclusive (i.e., less than or equal to ). + /// If false (default), the maximum version is exclusive (i.e., less than plus one). + /// + /// + /// The instance for chaining, configured with the specified supported software version range. + /// + public static InventorAddInEntryBuilder SupportedSoftwareVersion(this InventorAddInEntryBuilder builder, int minVersion, int maxVersion, bool maxVersionMinusOne = false) + { + return builder.SupportedSoftwareVersion(new Version(minVersion, 0), new Version(maxVersion, 0), maxVersionMinusOne); + } + + /// + /// Configures the supported Inventor software version range for the add-in entry builder. + /// + /// The instance to configure. + /// The minimum supported (inclusive if equal to , otherwise exclusive). + /// + /// The maximum supported (exclusive by default, or inclusive if is true). + /// If null, no upper bound is set. + /// + /// + /// If true, the maximum version is treated as inclusive (i.e., less than or equal to ). + /// If false (default), the maximum version is exclusive (i.e., less than plus one). + /// + /// + /// The instance for chaining, configured with the specified supported software version range. + /// + public static InventorAddInEntryBuilder SupportedSoftwareVersion(this InventorAddInEntryBuilder builder, Version minVersion, Version maxVersion, bool maxVersionMinusOne = false) + { + var minVersionString = minVersion.ToMajorString(); + var maxVersionString = maxVersion?.ToMajorString(); + + if (minVersionString == maxVersionString) + { + return builder.SupportedSoftwareVersionEqualTo(minVersionString); + } + + var greaterVersionString = minVersion.ToMajorString(-1); + builder.SupportedSoftwareVersionGreaterThan(greaterVersionString); + + if (maxVersion is null || maxVersion.Major == 0) + return builder; + + var lessVersionString = maxVersion.ToMajorString(1); + if (maxVersionMinusOne) + { + lessVersionString = maxVersionString; + } + + builder.SupportedSoftwareVersionLessThan(lessVersionString); + + return builder; + } + + + /// + /// Converts a object to a string containing only its major version followed by two dots. + /// + /// The instance to convert. + /// An optional value to add to the major version before converting to string. + /// + /// A string in the format "{major}..", where {major} is the major version number of the specified plus . + /// Returns null if is null. + /// + private static string ToMajorString(this Version version, int majorPlus = 0) + { + if (version is null) + return null; + + return $"{version.Major + majorPlus}.."; + } } diff --git a/CHANGELOG.md b/CHANGELOG.md index c160136..ef16431 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Add `InventorUtils` to support `InventorApplication` and `InventorPlatform`. - Rename `AddInEntryBuilder` to `RevitAddInEntryBuilder`. - Add `IInventorAddInEntryBuilder`, `InventorAddInEntryBuilder` and `InventorAddIn`. +- Update `InventorUtils` to have `SupportedSoftwareVersion` extension method. ### Tests - Add `DataBuild_Tests` to test `DataBuilder` - Add `PackageContentsBuilder_AutoCAD_Tests` and `PackageContentsBuilder_Revit_Tests`. From 4da887ede6ce74634850305ba6edcf6c82981e8c Mon Sep 17 00:00:00 2001 From: Luiz Henrique Cassettari Date: Wed, 4 Jun 2025 12:59:01 -0300 Subject: [PATCH 22/38] Update readme --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ef16431..788bcde 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [1.1.0] / 2025-05-16 ### Features - Support `AutoCAD` bundle. -- Support `Inventor` bundle. +- Support `Inventor` bundle and add-in. - Support custom `Element` and `Attribute`. - Add `IncludeSymbols` to support `SymbolPackageFormat`. ### PackageBuilder From 955da134305c839cd0810eba6de28bd42c101167 Mon Sep 17 00:00:00 2001 From: Luiz Henrique Cassettari Date: Wed, 4 Jun 2025 13:53:15 -0300 Subject: [PATCH 23/38] Add `Max3dsUtils` to support `Max3dsApplication` and `Max3dsPlatform`. --- .../Constants/AutodeskProducts.cs | 5 ++ Autodesk.PackageBuilder/Utils/Max3dsUtils.cs | 77 +++++++++++++++++++ Autodesk.PackageBuilder/Utils/RevitUtils.cs | 54 +++++++++++-- CHANGELOG.md | 1 + 4 files changed, 130 insertions(+), 7 deletions(-) create mode 100644 Autodesk.PackageBuilder/Utils/Max3dsUtils.cs diff --git a/Autodesk.PackageBuilder/Constants/AutodeskProducts.cs b/Autodesk.PackageBuilder/Constants/AutodeskProducts.cs index 9f56964..360799b 100644 --- a/Autodesk.PackageBuilder/Constants/AutodeskProducts.cs +++ b/Autodesk.PackageBuilder/Constants/AutodeskProducts.cs @@ -20,6 +20,11 @@ public static class AutodeskProducts /// public const string Inventor = "Inventor"; + /// + /// The product name for Autodesk 3ds Max. + /// + public const string Max3ds = "3ds Max"; + /// /// The product name for Autodesk Maya. /// diff --git a/Autodesk.PackageBuilder/Utils/Max3dsUtils.cs b/Autodesk.PackageBuilder/Utils/Max3dsUtils.cs new file mode 100644 index 0000000..47a1207 --- /dev/null +++ b/Autodesk.PackageBuilder/Utils/Max3dsUtils.cs @@ -0,0 +1,77 @@ +namespace Autodesk.PackageBuilder; + +/// +/// Provides utility extension methods for configuring 3ds Max-specific application packages and components. +/// +/// +/// For more information, see the 3ds Max Developer Documentation: +/// https://help.autodesk.com/view/3DSMAX/2019/ENU/?guid=__developer_writing_plug_ins_packaging_plugins_packagexml_example_html +/// +public static class Max3dsUtils +{ + /// + /// The default operating system for 3ds Max application packages (Windows 64-bit). + /// + public const string Os = "Win64"; + + /// + /// The default platform string for all 3ds Max-based products ("3ds Max"). + /// + public const string Platform = "3ds Max"; + + /// + /// Configures the for a 3ds Max application package. + /// + /// The application package builder instance. + /// + /// The instance for chaining, configured for 3ds Max. + /// + public static ApplicationPackageBuilder Max3dsApplication(this ApplicationPackageBuilder applicationPackageBuilder) + { + return applicationPackageBuilder + .ProductType(ProductTypes.Application) + .AutodeskProduct(AutodeskProducts.Max3ds); + } + + /// + /// Configures the for the default 3ds Max platform and operating system. + /// + /// The components builder instance. + /// The minimum supported 3ds Max version. If less than or equal to 0, the minimum version is not set. + /// The maximum supported 3ds Max version. If less than or equal to 0, the maximum version is not set. + /// + /// The instance for chaining, configured for 3ds Max's default OS and platform. + /// + public static ComponentsBuilder Max3dsPlatform(this ComponentsBuilder componentsBuilder, int max3dsMinVersion, int max3dsMaxVersion) + { + return componentsBuilder.Max3dsPlatform(max3dsMinVersion, max3dsMaxVersion); + } + + /// + /// Configures the for a specified operating system, platform, and 3ds Max version range. + /// + /// The components builder instance. + /// The operating system to set (e.g., "Win64"). + /// The platform to set (e.g., "3ds Max"). + /// The minimum supported 3ds Max version. If less than or equal to 0, the minimum version is not set. + /// The maximum supported 3ds Max version. If less than or equal to 0, the maximum version is not set. + /// + /// The instance for chaining, configured for the specified OS, platform, and version range. + /// + public static ComponentsBuilder Max3dsPlatform(this ComponentsBuilder componentsBuilder, string os, string platform, int max3dsMinVersion, int max3dsMaxVersion) + { + componentsBuilder.OS(os) + .Platform(platform); + + if (max3dsMinVersion > 0) + { + componentsBuilder.SeriesMin(max3dsMinVersion.ToString()); + } + if (max3dsMaxVersion > 0) + { + componentsBuilder.SeriesMax(max3dsMaxVersion.ToString()); + } + + return componentsBuilder; + } +} diff --git a/Autodesk.PackageBuilder/Utils/RevitUtils.cs b/Autodesk.PackageBuilder/Utils/RevitUtils.cs index 20c0674..ae8fbfd 100644 --- a/Autodesk.PackageBuilder/Utils/RevitUtils.cs +++ b/Autodesk.PackageBuilder/Utils/RevitUtils.cs @@ -40,7 +40,23 @@ public static ApplicationPackageBuilder RevitApplication(this ApplicationPackage /// public static ComponentsBuilder RevitPlatform(this ComponentsBuilder componentsBuilder, int revitVersion) { - return componentsBuilder.RevitPlatform(Os, Platform, revitVersion); + return componentsBuilder.RevitPlatform(revitVersion, revitVersion); + } + + /// + /// Configures the for the specified minimum and maximum Revit versions, + /// using "Win64" as the OS and "Revit" as the platform. + /// + /// The instance to configure. + /// The minimum Revit version (e.g., 2023). + /// The maximum Revit version (e.g., 2024). + /// + /// The configured instance with the specified minimum and maximum Revit versions, + /// "Win64" OS, and "Revit" platform. + /// + public static ComponentsBuilder RevitPlatform(this ComponentsBuilder componentsBuilder, int minRevitVersion, int maxRevitVersion) + { + return componentsBuilder.RevitPlatform(Os, Platform, minRevitVersion, maxRevitVersion); } /// @@ -52,13 +68,37 @@ public static ComponentsBuilder RevitPlatform(this ComponentsBuilder componentsB /// The Revit version (e.g., 2024). /// /// The configured instance with the specified OS, platform, and Revit version. - /// + /// /// public static ComponentsBuilder RevitPlatform(this ComponentsBuilder componentsBuilder, string os, string platform, int revitVersion) { - return componentsBuilder - .OS(os) - .Platform(platform) - .SeriesMin("R" + revitVersion) - .SeriesMax("R" + revitVersion); + return componentsBuilder.RevitPlatform(os, platform, revitVersion, revitVersion); + } + + /// + /// Configures the for the specified operating system, platform, and Revit version range. + /// + /// The instance to configure. + /// The operating system requirement (e.g., "Win64"). + /// The platform requirement (e.g., "Revit"). + /// The minimum supported Revit version (e.g., 2023). + /// The maximum supported Revit version (e.g., 2024). + /// + /// The configured instance with the specified OS, platform, and Revit version range. + /// + public static ComponentsBuilder RevitPlatform(this ComponentsBuilder componentsBuilder, string os, string platform, int minRevitVersion, int maxRevitVersion) + { + componentsBuilder.OS(os) + .Platform(platform); + + if (minRevitVersion > 0) + { + componentsBuilder.SeriesMin("R" + minRevitVersion.ToString()); + } + if (maxRevitVersion > 0) + { + componentsBuilder.SeriesMax("R" + maxRevitVersion.ToString()); + } + + return componentsBuilder; } } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 788bcde..081cb75 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Rename `AddInEntryBuilder` to `RevitAddInEntryBuilder`. - Add `IInventorAddInEntryBuilder`, `InventorAddInEntryBuilder` and `InventorAddIn`. - Update `InventorUtils` to have `SupportedSoftwareVersion` extension method. +- Add `Max3dsUtils` to support `Max3dsApplication` and `Max3dsPlatform`. ### Tests - Add `DataBuild_Tests` to test `DataBuilder` - Add `PackageContentsBuilder_AutoCAD_Tests` and `PackageContentsBuilder_Revit_Tests`. From 09c3123d00dff609d1ffbe214e82a81de318e68f Mon Sep 17 00:00:00 2001 From: Luiz Henrique Cassettari Date: Wed, 4 Jun 2025 14:13:53 -0300 Subject: [PATCH 24/38] Support `3ds Max` bundle --- .../PackageContentsBuilder_Inventor_Tests.cs | 62 +++++++++++++++++++ .../PackageContentsBuilder_Max3ds_Tests.cs | 62 +++++++++++++++++++ .../PackageContentsBuilder_Revit_Tests.cs | 5 +- Autodesk.PackageBuilder/Utils/Max3dsUtils.cs | 36 +++++++---- Autodesk.PackageBuilder/Utils/RevitUtils.cs | 34 +++++----- CHANGELOG.md | 3 + 6 files changed, 171 insertions(+), 31 deletions(-) create mode 100644 Autodesk.PackageBuilder.Tests/Application/PackageContentsBuilder_Inventor_Tests.cs create mode 100644 Autodesk.PackageBuilder.Tests/Application/PackageContentsBuilder_Max3ds_Tests.cs diff --git a/Autodesk.PackageBuilder.Tests/Application/PackageContentsBuilder_Inventor_Tests.cs b/Autodesk.PackageBuilder.Tests/Application/PackageContentsBuilder_Inventor_Tests.cs new file mode 100644 index 0000000..4ff7d06 --- /dev/null +++ b/Autodesk.PackageBuilder.Tests/Application/PackageContentsBuilder_Inventor_Tests.cs @@ -0,0 +1,62 @@ +using NUnit.Framework; + +namespace Autodesk.PackageBuilder.Tests.Application +{ + public class PackageContentsBuilder_Inventor_Tests + { + [Test] + public void Build_PackageBuilder_InventorClass() + { + var builder = BuilderUtils.Build(); + var content = builder.ToString(); +#if NET6_0 + if (InventorPackageBuilder.Expected.Equals(content) == false) + Assert.Ignore("Not equal, order not match in version net6.0 for some reason..."); +#endif + Assert.AreEqual(InventorPackageBuilder.Expected, content, $"Expected: {InventorPackageBuilder.Expected}\nContent: {content}"); + } + + public class InventorPackageBuilder : PackageContentsBuilder + { + public static string Expected => """" + + + + + + + + + + + + + """"; + public InventorPackageBuilder() + { + ApplicationPackage + .Create() + .InventorApplication() + .Name("InventorAddin") + .AppVersion("1.0.0"); + + CompanyDetails + .Create("Company Name") + .Url("url") + .Email("email"); + + Components + .CreateEntry("Inventor 2024") + .InventorPlatform() + .AppName("InventorAddin") + .ModuleName(@"./Contents/2024/InventorAddin.addin"); + + Components + .CreateEntry("Inventor 2025") + .InventorPlatform() + .AppName("InventorAddin") + .ModuleName(@"./Contents/2025/InventorAddin.addin"); + } + } + } +} \ No newline at end of file diff --git a/Autodesk.PackageBuilder.Tests/Application/PackageContentsBuilder_Max3ds_Tests.cs b/Autodesk.PackageBuilder.Tests/Application/PackageContentsBuilder_Max3ds_Tests.cs new file mode 100644 index 0000000..4e03fbf --- /dev/null +++ b/Autodesk.PackageBuilder.Tests/Application/PackageContentsBuilder_Max3ds_Tests.cs @@ -0,0 +1,62 @@ +using NUnit.Framework; + +namespace Autodesk.PackageBuilder.Tests.Application +{ + public class PackageContentsBuilder_Max3ds_Tests + { + [Test] + public void Build_PackageBuilder_Max3ds_Class() + { + var builder = BuilderUtils.Build(); + var content = builder.ToString(); +#if NET6_0 + if (Max3dsPackageBuilder.Expected.Equals(content) == false) + Assert.Ignore("Not equal, order not match in version net6.0 for some reason..."); +#endif + Assert.AreEqual(Max3dsPackageBuilder.Expected, content, $"Expected: {Max3dsPackageBuilder.Expected}\nContent: {content}"); + } + + public class Max3dsPackageBuilder : PackageContentsBuilder + { + public static string Expected => """" + + + + + + + + + + + + + """"; + public Max3dsPackageBuilder() + { + ApplicationPackage + .Create() + .Max3dsApplication() + .Name("Max3dsAddin") + .AppVersion("1.0.0"); + + CompanyDetails + .Create("Company Name") + .Url("url") + .Email("email"); + + Components + .CreateEntry("Max3ds 2024") + .Max3dsPlatform(2024) + .AppName("Max3dsAddin") + .ModuleName(@"./Contents/2024/Max3dsAddin.dll"); + + Components + .CreateEntry("Max3ds 2025") + .Max3dsPlatform(2025) + .AppName("Max3dsAddin") + .ModuleName(@"./Contents/2025/Max3dsAddin.dll"); + } + } + } +} \ No newline at end of file diff --git a/Autodesk.PackageBuilder.Tests/Application/PackageContentsBuilder_Revit_Tests.cs b/Autodesk.PackageBuilder.Tests/Application/PackageContentsBuilder_Revit_Tests.cs index c122354..30128d9 100644 --- a/Autodesk.PackageBuilder.Tests/Application/PackageContentsBuilder_Revit_Tests.cs +++ b/Autodesk.PackageBuilder.Tests/Application/PackageContentsBuilder_Revit_Tests.cs @@ -36,10 +36,9 @@ public RevitPackageBuilder() { ApplicationPackage .Create() - .AutodeskProduct(AutodeskProducts.Revit) + .RevitApplication() .Name("RevitAddin") - .AppVersion("1.0.0") - .ProductType(ProductTypes.Application); + .AppVersion("1.0.0"); CompanyDetails .Create("Company Name") diff --git a/Autodesk.PackageBuilder/Utils/Max3dsUtils.cs b/Autodesk.PackageBuilder/Utils/Max3dsUtils.cs index 47a1207..6b22549 100644 --- a/Autodesk.PackageBuilder/Utils/Max3dsUtils.cs +++ b/Autodesk.PackageBuilder/Utils/Max3dsUtils.cs @@ -33,18 +33,32 @@ public static ApplicationPackageBuilder Max3dsApplication(this ApplicationPackag .AutodeskProduct(AutodeskProducts.Max3ds); } + /// + /// Configures the for the default 3ds Max platform and operating system, + /// targeting a specific 3ds Max version. + /// + /// The components builder instance. + /// The 3ds Max version to target. + /// + /// The instance for chaining, configured for the specified 3ds Max version. + /// + public static ComponentsBuilder Max3dsPlatform(this ComponentsBuilder componentsBuilder, int version) + { + return componentsBuilder.Max3dsPlatform(version, version); + } + /// /// Configures the for the default 3ds Max platform and operating system. /// /// The components builder instance. - /// The minimum supported 3ds Max version. If less than or equal to 0, the minimum version is not set. - /// The maximum supported 3ds Max version. If less than or equal to 0, the maximum version is not set. + /// The minimum supported 3ds Max version. If less than or equal to 0, the minimum version is not set. + /// The maximum supported 3ds Max version. If less than or equal to 0, the maximum version is not set. /// /// The instance for chaining, configured for 3ds Max's default OS and platform. /// - public static ComponentsBuilder Max3dsPlatform(this ComponentsBuilder componentsBuilder, int max3dsMinVersion, int max3dsMaxVersion) + public static ComponentsBuilder Max3dsPlatform(this ComponentsBuilder componentsBuilder, int minVersion, int maxVersion) { - return componentsBuilder.Max3dsPlatform(max3dsMinVersion, max3dsMaxVersion); + return componentsBuilder.Max3dsPlatform(Os, Platform, minVersion, maxVersion); } /// @@ -53,23 +67,23 @@ public static ComponentsBuilder Max3dsPlatform(this ComponentsBuilder components /// The components builder instance. /// The operating system to set (e.g., "Win64"). /// The platform to set (e.g., "3ds Max"). - /// The minimum supported 3ds Max version. If less than or equal to 0, the minimum version is not set. - /// The maximum supported 3ds Max version. If less than or equal to 0, the maximum version is not set. + /// The minimum supported 3ds Max version. If less than or equal to 0, the minimum version is not set. + /// The maximum supported 3ds Max version. If less than or equal to 0, the maximum version is not set. /// /// The instance for chaining, configured for the specified OS, platform, and version range. /// - public static ComponentsBuilder Max3dsPlatform(this ComponentsBuilder componentsBuilder, string os, string platform, int max3dsMinVersion, int max3dsMaxVersion) + public static ComponentsBuilder Max3dsPlatform(this ComponentsBuilder componentsBuilder, string os, string platform, int minVersion, int maxVersion) { componentsBuilder.OS(os) .Platform(platform); - if (max3dsMinVersion > 0) + if (minVersion > 0) { - componentsBuilder.SeriesMin(max3dsMinVersion.ToString()); + componentsBuilder.SeriesMin(minVersion.ToString()); } - if (max3dsMaxVersion > 0) + if (maxVersion > 0) { - componentsBuilder.SeriesMax(max3dsMaxVersion.ToString()); + componentsBuilder.SeriesMax(maxVersion.ToString()); } return componentsBuilder; diff --git a/Autodesk.PackageBuilder/Utils/RevitUtils.cs b/Autodesk.PackageBuilder/Utils/RevitUtils.cs index ae8fbfd..95a4a58 100644 --- a/Autodesk.PackageBuilder/Utils/RevitUtils.cs +++ b/Autodesk.PackageBuilder/Utils/RevitUtils.cs @@ -34,13 +34,13 @@ public static ApplicationPackageBuilder RevitApplication(this ApplicationPackage /// Configures the for the specified Revit version, using "Win64" as the OS and "Revit" as the platform. /// /// The instance to configure. - /// The Revit version (e.g., 2024). + /// The Revit version (e.g., 2024). /// /// The configured instance with the specified Revit version, "Win64" OS, and "Revit" platform. /// - public static ComponentsBuilder RevitPlatform(this ComponentsBuilder componentsBuilder, int revitVersion) + public static ComponentsBuilder RevitPlatform(this ComponentsBuilder componentsBuilder, int version) { - return componentsBuilder.RevitPlatform(revitVersion, revitVersion); + return componentsBuilder.RevitPlatform(version, version); } /// @@ -48,15 +48,15 @@ public static ComponentsBuilder RevitPlatform(this ComponentsBuilder componentsB /// using "Win64" as the OS and "Revit" as the platform. /// /// The instance to configure. - /// The minimum Revit version (e.g., 2023). - /// The maximum Revit version (e.g., 2024). + /// The minimum Revit version (e.g., 2023). + /// The maximum Revit version (e.g., 2024). /// /// The configured instance with the specified minimum and maximum Revit versions, /// "Win64" OS, and "Revit" platform. /// - public static ComponentsBuilder RevitPlatform(this ComponentsBuilder componentsBuilder, int minRevitVersion, int maxRevitVersion) + public static ComponentsBuilder RevitPlatform(this ComponentsBuilder componentsBuilder, int minVersion, int maxVersion) { - return componentsBuilder.RevitPlatform(Os, Platform, minRevitVersion, maxRevitVersion); + return componentsBuilder.RevitPlatform(Os, Platform, minVersion, maxVersion); } /// @@ -65,13 +65,13 @@ public static ComponentsBuilder RevitPlatform(this ComponentsBuilder componentsB /// The instance to configure. /// The operating system (e.g., "Win64"). /// The platform (e.g., "Revit"). - /// The Revit version (e.g., 2024). + /// The Revit version (e.g., 2024). /// /// The configured instance with the specified OS, platform, and Revit version. /// /// - public static ComponentsBuilder RevitPlatform(this ComponentsBuilder componentsBuilder, string os, string platform, int revitVersion) + public static ComponentsBuilder RevitPlatform(this ComponentsBuilder componentsBuilder, string os, string platform, int version) { - return componentsBuilder.RevitPlatform(os, platform, revitVersion, revitVersion); + return componentsBuilder.RevitPlatform(os, platform, version, version); } /// @@ -80,23 +80,23 @@ public static ComponentsBuilder RevitPlatform(this ComponentsBuilder componentsB /// The instance to configure. /// The operating system requirement (e.g., "Win64"). /// The platform requirement (e.g., "Revit"). - /// The minimum supported Revit version (e.g., 2023). - /// The maximum supported Revit version (e.g., 2024). + /// The minimum supported Revit version (e.g., 2023). + /// The maximum supported Revit version (e.g., 2024). /// /// The configured instance with the specified OS, platform, and Revit version range. /// - public static ComponentsBuilder RevitPlatform(this ComponentsBuilder componentsBuilder, string os, string platform, int minRevitVersion, int maxRevitVersion) + public static ComponentsBuilder RevitPlatform(this ComponentsBuilder componentsBuilder, string os, string platform, int minVersion, int maxVersion) { componentsBuilder.OS(os) .Platform(platform); - if (minRevitVersion > 0) + if (minVersion > 0) { - componentsBuilder.SeriesMin("R" + minRevitVersion.ToString()); + componentsBuilder.SeriesMin("R" + minVersion.ToString()); } - if (maxRevitVersion > 0) + if (maxVersion > 0) { - componentsBuilder.SeriesMax("R" + maxRevitVersion.ToString()); + componentsBuilder.SeriesMax("R" + maxVersion.ToString()); } return componentsBuilder; diff --git a/CHANGELOG.md b/CHANGELOG.md index 081cb75..018a5ef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ### Features - Support `AutoCAD` bundle. - Support `Inventor` bundle and add-in. +- Support `3ds Max` bundle. - Support custom `Element` and `Attribute`. - Add `IncludeSymbols` to support `SymbolPackageFormat`. ### PackageBuilder @@ -26,6 +27,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Add `DataBuild_Tests` to test `DataBuilder` - Add `PackageContentsBuilder_AutoCAD_Tests` and `PackageContentsBuilder_Revit_Tests`. - Add `InventorAddInsBuilder_Tests` to test `InventorAddInEntryBuilder`. +- Add `PackageContentsBuilder_Inventor_Tests` to test `InventorUtils`. +- Add `PackageContentsBuilder_Max3ds_Tests` to test `Max3dsUtils`. ## [1.0.6] / 2023-11-24 - 2023-12-06 ### Features From f198d7b0353adbfaee446a71b44c86f63898d203 Mon Sep 17 00:00:00 2001 From: Luiz Henrique Cassettari Date: Wed, 4 Jun 2025 15:40:47 -0300 Subject: [PATCH 25/38] Update `InventorUtils` to use `SeriesMin/SeriesMax` for `App Store` only. --- .../PackageContentsBuilder_Inventor_Tests.cs | 8 +- .../Utils/InventorUtils.cs | 89 +++++++++++++++++++ CHANGELOG.md | 1 + README.md | 21 ++++- 4 files changed, 114 insertions(+), 5 deletions(-) diff --git a/Autodesk.PackageBuilder.Tests/Application/PackageContentsBuilder_Inventor_Tests.cs b/Autodesk.PackageBuilder.Tests/Application/PackageContentsBuilder_Inventor_Tests.cs index 4ff7d06..c7d0eaf 100644 --- a/Autodesk.PackageBuilder.Tests/Application/PackageContentsBuilder_Inventor_Tests.cs +++ b/Autodesk.PackageBuilder.Tests/Application/PackageContentsBuilder_Inventor_Tests.cs @@ -23,11 +23,11 @@ public class InventorPackageBuilder : PackageContentsBuilder - + - + @@ -47,13 +47,13 @@ public InventorPackageBuilder() Components .CreateEntry("Inventor 2024") - .InventorPlatform() + .InventorPlatform(25, 29, true) .AppName("InventorAddin") .ModuleName(@"./Contents/2024/InventorAddin.addin"); Components .CreateEntry("Inventor 2025") - .InventorPlatform() + .InventorPlatform(29, 0) .AppName("InventorAddin") .ModuleName(@"./Contents/2025/InventorAddin.addin"); } diff --git a/Autodesk.PackageBuilder/Utils/InventorUtils.cs b/Autodesk.PackageBuilder/Utils/InventorUtils.cs index a9e9191..76e6c96 100644 --- a/Autodesk.PackageBuilder/Utils/InventorUtils.cs +++ b/Autodesk.PackageBuilder/Utils/InventorUtils.cs @@ -65,6 +65,87 @@ public static ComponentsBuilder InventorPlatform(this ComponentsBuilder componen .Platform(platform); } + /// + /// Configures the for the default Inventor platform and operating system, + /// and restricts the supported internal Inventor version range using integer major versions. + /// + /// The instance to configure. + /// The minimum supported internal Inventor version as an integer (e.g., 25 for Inventor 2021). + /// The maximum supported internal Inventor version as an integer. + /// + /// If true, the maximum version is treated as inclusive (i.e., less than or equal to ). + /// If false (default), the maximum version is exclusive (i.e., less than minus one). + /// + /// + /// The instance for chaining, configured for Inventor's default OS, platform, and version range. + /// + public static ComponentsBuilder InventorPlatform(this ComponentsBuilder componentsBuilder, int minInternalVersion, int maxInternalVersion, bool maxVersionMinusOne = false) + { + return componentsBuilder.InventorPlatform(new Version(minInternalVersion, 0), new Version(maxInternalVersion, 0), maxVersionMinusOne); + } + + /// + /// Configures the for the default Inventor platform and operating system, + /// and restricts the supported internal Inventor version range. + /// + /// The instance to configure. + /// The minimum supported internal Inventor version as a (e.g., 25 for Inventor 2021). + /// The maximum supported internal Inventor version as a . + /// + /// If true, the maximum version is treated as inclusive (i.e., less than or equal to ). + /// If false (default), the maximum version is exclusive (i.e., less than minus one). + /// + /// + /// The instance for chaining, configured for Inventor's default OS, platform, and version range. + /// + public static ComponentsBuilder InventorPlatform(this ComponentsBuilder componentsBuilder, Version minVersion, Version maxVersion, bool maxVersionMinusOne = false) + { + return componentsBuilder.InventorPlatform(Os, Platform, minVersion, maxVersion, maxVersionMinusOne); + } + + /// + /// Configures the for a specified operating system, platform, and Inventor version range. + /// + /// The instance to configure. + /// The operating system to set (e.g., "Win64"). + /// The platform to set (e.g., "Inventor"). + /// The minimum supported internal Inventor version as a (e.g., 25 for Inventor 2021). + /// The maximum supported internal Inventor version as a . If null or major is 0, no upper bound is set. + /// + /// If true, the maximum version is treated as inclusive (i.e., less than or equal to ). + /// If false (default), the maximum version is exclusive (i.e., less than minus one). + /// + /// + /// The instance for chaining, configured for the specified OS, platform, and version range. + /// + public static ComponentsBuilder InventorPlatform(this ComponentsBuilder componentsBuilder, string os, string platform, Version minVersion, Version maxVersion, bool maxVersionMinusOne = false) + { + var minVersionString = minVersion.ToIrMajorString(); + var maxVersionString = maxVersion?.ToIrMajorString(); + + componentsBuilder + .OS(os) + .Platform(platform) + .SeriesMin(minVersionString); + + if (minVersionString == maxVersionString) + { + return componentsBuilder + .SeriesMax(maxVersionString); + } + + if (maxVersion is null || maxVersion.Major == 0) + return componentsBuilder; + + if (maxVersionMinusOne) + { + maxVersionString = maxVersion.ToIrMajorString(-1); + } + + return componentsBuilder + .SeriesMax(maxVersionString); + } + /// /// Configures the supported Inventor software version for the add-in entry builder using an integer major version. /// @@ -171,4 +252,12 @@ private static string ToMajorString(this Version version, int majorPlus = 0) return $"{version.Major + majorPlus}.."; } + + private static string ToIrMajorString(this Version version, int majorPlus = 0) + { + if (version is null) + return null; + + return $"Ir{version.Major + majorPlus}"; + } } diff --git a/CHANGELOG.md b/CHANGELOG.md index 018a5ef..b27d29d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Add `IInventorAddInEntryBuilder`, `InventorAddInEntryBuilder` and `InventorAddIn`. - Update `InventorUtils` to have `SupportedSoftwareVersion` extension method. - Add `Max3dsUtils` to support `Max3dsApplication` and `Max3dsPlatform`. +- Update `InventorUtils` to use `SeriesMin/SeriesMax` for `App Store` only. ### Tests - Add `DataBuild_Tests` to test `DataBuilder` - Add `PackageContentsBuilder_AutoCAD_Tests` and `PackageContentsBuilder_Revit_Tests`. diff --git a/README.md b/README.md index b98a28a..e87a230 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,11 @@ This package is intended to build Autodesk `PackageContent.xml` and `RevitAddin.addin` using C# fluent API. [![Autodesk](https://img.shields.io/badge/Autodesk-black?logo=autodesk&logoColor=white)](https://github.com/ricaun-io/Autodesk.PackageBuilder) -[![Revit](https://img.shields.io/badge/Revit-black.svg)](https://github.com/ricaun-io/Autodesk.PackageBuilder) +[![AutoCAD](https://img.shields.io/badge/AutoCAD-E51050.svg)](https://github.com/ricaun-io/Autodesk.PackageBuilder) +[![Revit](https://img.shields.io/badge/Revit-186BFF.svg)](https://github.com/ricaun-io/Autodesk.PackageBuilder) +[![3ds Max](https://img.shields.io/badge/3ds%20Max-37A5CC.svg)](https://github.com/ricaun-io/Autodesk.PackageBuilder) +[![Maya](https://img.shields.io/badge/Maya-37A5CC.svg)](https://github.com/ricaun-io/Autodesk.PackageBuilder) +[![Inventor](https://img.shields.io/badge/Inventor-DBAE03.svg)](https://github.com/ricaun-io/Autodesk.PackageBuilder) [![Visual Studio 2022](https://img.shields.io/badge/Visual%20Studio-2022-blue)](https://github.com/ricaun-io/Autodesk.PackageBuilder) [![Nuke](https://img.shields.io/badge/Nuke-Build-blue)](https://nuke.build/) @@ -11,6 +15,21 @@ This package is intended to build Autodesk `PackageContent.xml` and `RevitAddin. [![Build](https://github.com/ricaun-io/Autodesk.PackageBuilder/actions/workflows/Build.yml/badge.svg)](https://github.com/ricaun-io/Autodesk.PackageBuilder/actions) [![Release](https://img.shields.io/nuget/v/Autodesk.PackageBuilder?logo=nuget&label=release&color=blue)](https://www.nuget.org/packages/Autodesk.PackageBuilder) +## Autodesk Product Version Table + +| Product | RuntimeRequirements::SeriesMin/SeriesMax | RuntimeRequirements::Platform | +|--------------|------------------------------------------|--------------------------------------| +| AutoCAD | R24.0 (2021), R23.1 (2020), R23.0 (2019) | AutoCAD* | +| Revit | R2021, R2020, R2019, R2018, R2017 | Revit | +| Maya | 2020, 2019, 2018, ... | Maya | +| 3ds Max | 2021, 2020, 2019, 2018, ... | 3ds Max|3ds Max Design | +| Inventor | (version is taken from add-in manifest) | Inventor | +| Navisworks | Nw18 (2021), Nw17 (2020), Nw16 (2019) | NAVMAN|NAVSIM | +| Vault | V2020, V2019, ... | Vault | +| Fusion 360 | (No version, leave empty) | Fusion 360 | + +* [AppBundle: Autodesk Products - 2020](https://www.autodesk.com/autodesk-university/class/AppBundle-Cross-Distribution-Autodesk-Products-App-Store-and-Forge-2020) + ## Examples ### Create PackageContents.xml From 23015b05ed5b9ed0e4ea2986eae1b5f55e69eb5f Mon Sep 17 00:00:00 2001 From: Luiz Henrique Cassettari Date: Wed, 4 Jun 2025 15:45:03 -0300 Subject: [PATCH 26/38] Support `Maya` bundle --- .../PackageContentsBuilder_Maya_Tests.cs | 63 +++++++++++++ Autodesk.PackageBuilder/Utils/MayaUtils.cs | 91 +++++++++++++++++++ CHANGELOG.md | 1 + 3 files changed, 155 insertions(+) create mode 100644 Autodesk.PackageBuilder.Tests/Application/PackageContentsBuilder_Maya_Tests.cs create mode 100644 Autodesk.PackageBuilder/Utils/MayaUtils.cs diff --git a/Autodesk.PackageBuilder.Tests/Application/PackageContentsBuilder_Maya_Tests.cs b/Autodesk.PackageBuilder.Tests/Application/PackageContentsBuilder_Maya_Tests.cs new file mode 100644 index 0000000..846365b --- /dev/null +++ b/Autodesk.PackageBuilder.Tests/Application/PackageContentsBuilder_Maya_Tests.cs @@ -0,0 +1,63 @@ +using NUnit.Framework; + +namespace Autodesk.PackageBuilder.Tests.Application +{ + public class PackageContentsBuilder_Maya_Tests + { + [Test] + public void Build_PackageBuilder_Maya_Class() + { + var builder = BuilderUtils.Build(); + var content = builder.ToString(); +#if NET6_0 + if (MayaPackageBuilder.Expected.Equals(content) == false) + Assert.Ignore("Not equal, order not match in version net6.0 for some reason..."); +#endif + Assert.AreEqual(MayaPackageBuilder.Expected, content, $"Expected: {MayaPackageBuilder.Expected}\nContent: {content}"); + } + + public class MayaPackageBuilder : PackageContentsBuilder + { + public static string Expected => """" + + + + + + + + + + + + + """"; + + public MayaPackageBuilder() + { + ApplicationPackage + .Create() + .MayaApplication() + .Name("MayaAddin") + .AppVersion("1.0.0"); + + CompanyDetails + .Create("Company Name") + .Url("url") + .Email("email"); + + Components + .CreateEntry("Maya 2024") + .MayaPlatform(2024) + .AppName("MayaAddin") + .ModuleName(@"./Contents/2024/MayaAddin.dll"); + + Components + .CreateEntry("Maya 2025") + .MayaPlatform(2025) + .AppName("MayaAddin") + .ModuleName(@"./Contents/2025/MayaAddin.dll"); + } + } + } +} \ No newline at end of file diff --git a/Autodesk.PackageBuilder/Utils/MayaUtils.cs b/Autodesk.PackageBuilder/Utils/MayaUtils.cs new file mode 100644 index 0000000..eba8ac5 --- /dev/null +++ b/Autodesk.PackageBuilder/Utils/MayaUtils.cs @@ -0,0 +1,91 @@ +namespace Autodesk.PackageBuilder; + +/// +/// Provides utility extension methods for configuring Maya-specific application packages and components. +/// +/// +/// For more information, see the Maya Developer Documentation: +/// https://help.autodesk.com/view/MAYAUL/2024/ENU/?guid=Maya_SDK_Distributing_Maya_Plug_ins_DistributingViaTheAppStore_html +/// +public static class MayaUtils +{ + /// + /// The default operating system for Maya application packages (Windows 64-bit). + /// + public const string Os = "Win64"; + + /// + /// The default platform string for all Maya-based products ("Maya"). + /// + public const string Platform = "Maya"; + + /// + /// Configures the for a Maya application package. + /// + /// The application package builder instance. + /// + /// The instance for chaining, configured for Maya. + /// + public static ApplicationPackageBuilder MayaApplication(this ApplicationPackageBuilder applicationPackageBuilder) + { + return applicationPackageBuilder + .ProductType(ProductTypes.Application) + .AutodeskProduct(AutodeskProducts.Maya); + } + + /// + /// Configures the for the default Maya platform and operating system, + /// targeting a specific Maya version. + /// + /// The components builder instance. + /// The Maya version to target. + /// + /// The instance for chaining, configured for the specified Maya version. + /// + public static ComponentsBuilder MayaPlatform(this ComponentsBuilder componentsBuilder, int version) + { + return componentsBuilder.MayaPlatform(version, version); + } + + /// + /// Configures the for the default Maya platform and operating system. + /// + /// The components builder instance. + /// The minimum supported Maya version. If less than or equal to 0, the minimum version is not set. + /// The maximum supported Maya version. If less than or equal to 0, the maximum version is not set. + /// + /// The instance for chaining, configured for Maya's default OS and platform. + /// + public static ComponentsBuilder MayaPlatform(this ComponentsBuilder componentsBuilder, int minVersion, int maxVersion) + { + return componentsBuilder.MayaPlatform(Os, Platform, minVersion, maxVersion); + } + + /// + /// Configures the for a specified operating system, platform, and Maya version range. + /// + /// The components builder instance. + /// The operating system to set (e.g., "Win64"). + /// The platform to set (e.g., "Maya"). + /// The minimum supported Maya version. If less than or equal to 0, the minimum version is not set. + /// The maximum supported Maya version. If less than or equal to 0, the maximum version is not set. + /// + /// The instance for chaining, configured for the specified OS, platform, and version range. + /// + public static ComponentsBuilder MayaPlatform(this ComponentsBuilder componentsBuilder, string os, string platform, int minVersion, int maxVersion) + { + componentsBuilder.OS(os) + .Platform(platform); + + if (minVersion > 0) + { + componentsBuilder.SeriesMin(minVersion.ToString()); + } + if (maxVersion > 0) + { + componentsBuilder.SeriesMax(maxVersion.ToString()); + } + + return componentsBuilder; + } +} diff --git a/CHANGELOG.md b/CHANGELOG.md index b27d29d..5208262 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Support `AutoCAD` bundle. - Support `Inventor` bundle and add-in. - Support `3ds Max` bundle. +- Support `Maya` bundle. - Support custom `Element` and `Attribute`. - Add `IncludeSymbols` to support `SymbolPackageFormat`. ### PackageBuilder From 4003e0391caff6f1132c8330882d4406102d7724 Mon Sep 17 00:00:00 2001 From: Luiz Henrique Cassettari Date: Wed, 4 Jun 2025 15:53:17 -0300 Subject: [PATCH 27/38] Update readme --- README.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index e87a230..6fea5a0 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Autodesk.PackageBuilder -This package is intended to build Autodesk `PackageContent.xml` and `RevitAddin.addin` using C# fluent API. +This package is intended to build Autodesk `PackageContent.xml` and `RevitAddin.addin/InventorAddin.addin` using C# fluent API. [![Autodesk](https://img.shields.io/badge/Autodesk-black?logo=autodesk&logoColor=white)](https://github.com/ricaun-io/Autodesk.PackageBuilder) [![AutoCAD](https://img.shields.io/badge/AutoCAD-E51050.svg)](https://github.com/ricaun-io/Autodesk.PackageBuilder) @@ -8,6 +8,9 @@ This package is intended to build Autodesk `PackageContent.xml` and `RevitAddin. [![3ds Max](https://img.shields.io/badge/3ds%20Max-37A5CC.svg)](https://github.com/ricaun-io/Autodesk.PackageBuilder) [![Maya](https://img.shields.io/badge/Maya-37A5CC.svg)](https://github.com/ricaun-io/Autodesk.PackageBuilder) [![Inventor](https://img.shields.io/badge/Inventor-DBAE03.svg)](https://github.com/ricaun-io/Autodesk.PackageBuilder) +[![Navisworks](https://img.shields.io/badge/Navisworks-186BFF.svg)](https://github.com/ricaun-io/Autodesk.PackageBuilder) +[![Vault](https://img.shields.io/badge/Vault-DBAE03.svg)](https://github.com/ricaun-io/Autodesk.PackageBuilder) +[![Fusion 360](https://img.shields.io/badge/Fusion%20360-FF6B00.svg)](https://github.com/ricaun-io/Autodesk.PackageBuilder) [![Visual Studio 2022](https://img.shields.io/badge/Visual%20Studio-2022-blue)](https://github.com/ricaun-io/Autodesk.PackageBuilder) [![Nuke](https://img.shields.io/badge/Nuke-Build-blue)](https://nuke.build/) @@ -17,15 +20,15 @@ This package is intended to build Autodesk `PackageContent.xml` and `RevitAddin. ## Autodesk Product Version Table -| Product | RuntimeRequirements::SeriesMin/SeriesMax | RuntimeRequirements::Platform | +| Product | RuntimeRequirements::SeriesMin/SeriesMax | RuntimeRequirements::Platform | |--------------|------------------------------------------|--------------------------------------| | AutoCAD | R24.0 (2021), R23.1 (2020), R23.0 (2019) | AutoCAD* | | Revit | R2021, R2020, R2019, R2018, R2017 | Revit | -| Maya | 2020, 2019, 2018, ... | Maya | +| Maya | 2021, 2020, 2019, 2018, ... | Maya | | 3ds Max | 2021, 2020, 2019, 2018, ... | 3ds Max|3ds Max Design | | Inventor | (version is taken from add-in manifest) | Inventor | | Navisworks | Nw18 (2021), Nw17 (2020), Nw16 (2019) | NAVMAN|NAVSIM | -| Vault | V2020, V2019, ... | Vault | +| Vault | V2021, V2020, V2019, ... | Vault | | Fusion 360 | (No version, leave empty) | Fusion 360 | * [AppBundle: Autodesk Products - 2020](https://www.autodesk.com/autodesk-university/class/AppBundle-Cross-Distribution-Autodesk-Products-App-Store-and-Forge-2020) From 69e5c0de3d2d2d5a82221acc43c900ab67cfe6c3 Mon Sep 17 00:00:00 2001 From: Luiz Henrique Cassettari Date: Wed, 4 Jun 2025 17:34:57 -0300 Subject: [PATCH 28/38] Add `NavisworksUtils` to support `NavisworksApplication` and `NavisworksPlatform`. --- ...PackageContentsBuilder_Navisworks_Tests.cs | 63 +++++++ .../Utils/NavisworksUtils.cs | 169 ++++++++++++++++++ CHANGELOG.md | 5 + Directory.Build.props | 2 +- 4 files changed, 238 insertions(+), 1 deletion(-) create mode 100644 Autodesk.PackageBuilder.Tests/Application/PackageContentsBuilder_Navisworks_Tests.cs create mode 100644 Autodesk.PackageBuilder/Utils/NavisworksUtils.cs diff --git a/Autodesk.PackageBuilder.Tests/Application/PackageContentsBuilder_Navisworks_Tests.cs b/Autodesk.PackageBuilder.Tests/Application/PackageContentsBuilder_Navisworks_Tests.cs new file mode 100644 index 0000000..86a122e --- /dev/null +++ b/Autodesk.PackageBuilder.Tests/Application/PackageContentsBuilder_Navisworks_Tests.cs @@ -0,0 +1,63 @@ +using NUnit.Framework; + +namespace Autodesk.PackageBuilder.Tests.Application +{ + public class PackageContentsBuilder_Navisworks_Tests + { + [Test] + public void Build_PackageBuilder_NavisworksClass() + { + var builder = BuilderUtils.Build(); + var content = builder.ToString(); +#if NET6_0 + if (NavisworksPackageBuilder.Expected.Equals(content) == false) + Assert.Ignore("Not equal, order not match in version net6.0 for some reason..."); +#endif + Assert.AreEqual(NavisworksPackageBuilder.Expected, content, $"Expected: {NavisworksPackageBuilder.Expected}\nContent: {content}"); + } + + public class NavisworksPackageBuilder : PackageContentsBuilder + { + public static string Expected => """" + + + + + + + + + + + + + """"; + + public NavisworksPackageBuilder() + { + ApplicationPackage + .Create() + .AutodeskProduct("Navisworks") + .Name("NavisworksAddin") + .AppVersion("1.0.0"); + + CompanyDetails + .Create("Company Name") + .Url("url") + .Email("email"); + + Components + .CreateEntry("Navisworks 2024") + .NavisworksPlatform(19, 22, true) + .AppName("NavisworksAddin") + .ModuleName(@"./Contents/2024/NavisworksAddin.dll"); + + Components + .CreateEntry("Navisworks 2025") + .NavisworksPlatform(22, 0) + .AppName("NavisworksAddin") + .ModuleName(@"./Contents/2025/NavisworksAddin.dll"); + } + } + } +} \ No newline at end of file diff --git a/Autodesk.PackageBuilder/Utils/NavisworksUtils.cs b/Autodesk.PackageBuilder/Utils/NavisworksUtils.cs new file mode 100644 index 0000000..b34e261 --- /dev/null +++ b/Autodesk.PackageBuilder/Utils/NavisworksUtils.cs @@ -0,0 +1,169 @@ +using System; + +namespace Autodesk.PackageBuilder; + +/// +/// Provides utility extension methods for configuring Navisworks-specific application packages and components. +/// +/// +/// For more information, see the Navisworks Developer Documentation: +/// https://aps.autodesk.com/developer/overview/navisworks +/// https://adndevblog.typepad.com/aec/navisworks/ +/// +public static class NavisworksUtils +{ + /// + /// The default operating system for Navisworks application packages (Windows 64-bit). + /// + public const string Os = "Win64"; + + /// + /// The default platform string for all Navisworks-based products ("NAVMAN|NAVSIM"). + /// + public const string Platform = "NAVMAN|NAVSIM"; + + /// + /// Configures the for a Navisworks application package. + /// + /// The application package builder instance. + /// + /// The instance for chaining, configured for Navisworks. + /// + public static ApplicationPackageBuilder NavisworksApplication(this ApplicationPackageBuilder applicationPackageBuilder) + { + return applicationPackageBuilder + .ProductType(ProductTypes.Application) + .AutodeskProduct(AutodeskProducts.Navisworks); + } + + /// + /// Configures the for the default Navisworks platform and operating system. + /// + /// The components builder instance. + /// + /// The instance for chaining, configured for Navisworks's default OS and platform. + /// + public static ComponentsBuilder NavisworksPlatform(this ComponentsBuilder componentsBuilder) + { + return componentsBuilder + .OS(Os) + .Platform(Platform); + } + + /// + /// Configures the for a specified operating system and platform. + /// + /// The components builder instance. + /// The operating system to set. + /// The platform to set. + /// + /// The instance for chaining, configured for the specified OS and platform. + /// + public static ComponentsBuilder NavisworksPlatform(this ComponentsBuilder componentsBuilder, string os, string platform) + { + return componentsBuilder + .OS(os) + .Platform(platform); + } + + /// + /// Configures the for the default Navisworks platform and operating system, + /// and restricts the supported internal Navisworks version range using integer major versions. + /// + /// The instance to configure. + /// The minimum supported internal Navisworks version as an integer. + /// The maximum supported internal Navisworks version as an integer. + /// + /// If true, the maximum version is treated as inclusive (i.e., less than or equal to ). + /// If false (default), the maximum version is exclusive (i.e., less than minus one). + /// + /// + /// The instance for chaining, configured for Navisworks's default OS, platform, and version range. + /// + public static ComponentsBuilder NavisworksPlatform(this ComponentsBuilder componentsBuilder, int minInternalVersion, int maxInternalVersion, bool maxVersionMinusOne = false) + { + return componentsBuilder.NavisworksPlatform(new Version(minInternalVersion, 0), new Version(maxInternalVersion, 0), maxVersionMinusOne); + } + + /// + /// Configures the for the default Navisworks platform and operating system, + /// and restricts the supported internal Navisworks version range. + /// + /// The instance to configure. + /// The minimum supported internal Navisworks version as a . + /// The maximum supported internal Navisworks version as a . + /// + /// If true, the maximum version is treated as inclusive (i.e., less than or equal to ). + /// If false (default), the maximum version is exclusive (i.e., less than minus one). + /// + /// + /// The instance for chaining, configured for Navisworks's default OS, platform, and version range. + /// + public static ComponentsBuilder NavisworksPlatform(this ComponentsBuilder componentsBuilder, Version minVersion, Version maxVersion, bool maxVersionMinusOne = false) + { + return componentsBuilder.NavisworksPlatform(Os, Platform, minVersion, maxVersion, maxVersionMinusOne); + } + + /// + /// Configures the for a specified operating system, platform, and Navisworks version range. + /// + /// The instance to configure. + /// The operating system to set (e.g., "Win64"). + /// The platform to set (e.g., "NAVMAN|NAVSIM"). + /// The minimum supported internal Navisworks version as a . + /// The maximum supported internal Navisworks version as a . If null or major is 0, no upper bound is set. + /// + /// If true, the maximum version is treated as inclusive (i.e., less than or equal to ). + /// If false (default), the maximum version is exclusive (i.e., less than minus one). + /// + /// + /// The instance for chaining, configured for the specified OS, platform, and version range. + /// + public static ComponentsBuilder NavisworksPlatform(this ComponentsBuilder componentsBuilder, string os, string platform, Version minVersion, Version maxVersion, bool maxVersionMinusOne = false) + { + var minVersionString = minVersion.ToNavisworksMajorString(); + var maxVersionString = maxVersion?.ToNavisworksMajorString(); + + componentsBuilder + .OS(os) + .Platform(platform) + .SeriesMin(minVersionString); + + if (minVersionString == maxVersionString) + { + return componentsBuilder + .SeriesMax(maxVersionString); + } + + if (maxVersion is null || maxVersion.Major == 0) + return componentsBuilder; + + if (maxVersionMinusOne) + { + maxVersionString = maxVersion.ToNavisworksMajorString(-1); + } + + return componentsBuilder + .SeriesMax(maxVersionString); + } + + + /// + /// Converts a object to a Navisworks major version string (e.g., "Nw21"). + /// + /// The instance to convert. + /// + /// An optional integer to add to the major version. Defaults to 0. + /// Use negative values to decrement the major version (e.g., for exclusive upper bounds). + /// + /// + /// A string in the format "Nw{major}", or null if is null. + /// + private static string ToNavisworksMajorString(this Version version, int majorPlus = 0) + { + if (version is null) + return null; + + return $"Nw{version.Major + majorPlus}"; + } +} diff --git a/CHANGELOG.md b/CHANGELOG.md index 5208262..b7ff9ec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Support `Inventor` bundle and add-in. - Support `3ds Max` bundle. - Support `Maya` bundle. +- Support `Maya` bundle. - Support custom `Element` and `Attribute`. - Add `IncludeSymbols` to support `SymbolPackageFormat`. ### PackageBuilder @@ -25,12 +26,16 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Update `InventorUtils` to have `SupportedSoftwareVersion` extension method. - Add `Max3dsUtils` to support `Max3dsApplication` and `Max3dsPlatform`. - Update `InventorUtils` to use `SeriesMin/SeriesMax` for `App Store` only. +- Add `MayaUtils` to support `MayaApplication` and `MayaPlatform`. +- Add `NavisworksUtils` to support `NavisworksApplication` and `NavisworksPlatform`. ### Tests - Add `DataBuild_Tests` to test `DataBuilder` - Add `PackageContentsBuilder_AutoCAD_Tests` and `PackageContentsBuilder_Revit_Tests`. - Add `InventorAddInsBuilder_Tests` to test `InventorAddInEntryBuilder`. - Add `PackageContentsBuilder_Inventor_Tests` to test `InventorUtils`. - Add `PackageContentsBuilder_Max3ds_Tests` to test `Max3dsUtils`. +- Add `PackageContentsBuilder_Maya_Tests` to test `MayaUtils`. +- Add `PackageContentsBuilder_Navisworks_Tests` to test `NavisworksUtils`. ## [1.0.6] / 2023-11-24 - 2023-12-06 ### Features diff --git a/Directory.Build.props b/Directory.Build.props index 95d7f72..3f05556 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,5 +1,5 @@ - 1.1.0-beta.10 + 1.1.0-beta.11 \ No newline at end of file From 9cc58068f5d8b73df46406e3c272247665058feb Mon Sep 17 00:00:00 2001 From: Luiz Henrique Cassettari Date: Wed, 4 Jun 2025 17:36:30 -0300 Subject: [PATCH 29/38] Update readme --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 6fea5a0..e209f86 100644 --- a/README.md +++ b/README.md @@ -9,8 +9,10 @@ This package is intended to build Autodesk `PackageContent.xml` and `RevitAddin. [![Maya](https://img.shields.io/badge/Maya-37A5CC.svg)](https://github.com/ricaun-io/Autodesk.PackageBuilder) [![Inventor](https://img.shields.io/badge/Inventor-DBAE03.svg)](https://github.com/ricaun-io/Autodesk.PackageBuilder) [![Navisworks](https://img.shields.io/badge/Navisworks-186BFF.svg)](https://github.com/ricaun-io/Autodesk.PackageBuilder) + [![Visual Studio 2022](https://img.shields.io/badge/Visual%20Studio-2022-blue)](https://github.com/ricaun-io/Autodesk.PackageBuilder) [![Nuke](https://img.shields.io/badge/Nuke-Build-blue)](https://nuke.build/) From beaa03e9c03170f0e90610ef0b5fa70910b9293f Mon Sep 17 00:00:00 2001 From: Luiz Henrique Cassettari Date: Wed, 4 Jun 2025 17:42:02 -0300 Subject: [PATCH 30/38] Version 1.1.0-rc --- Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Build.props b/Directory.Build.props index 3f05556..7821863 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,5 +1,5 @@ - 1.1.0-beta.11 + 1.1.0-rc \ No newline at end of file From ee5c886d757fd7a0e02bf6513143aea281f70110 Mon Sep 17 00:00:00 2001 From: Luiz Henrique Cassettari Date: Wed, 4 Jun 2025 17:55:14 -0300 Subject: [PATCH 31/38] Update to version 2.0.0-rc --- CHANGELOG.md | 4 ++-- Directory.Build.props | 2 +- README.md | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b7ff9ec..9d6c4aa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). -## [1.1.0] / 2025-05-16 +## [2.0.0] / 2025-05-16 ### Features - Support `AutoCAD` bundle. - Support `Inventor` bundle and add-in. @@ -89,7 +89,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - First Release [vNext]: ../../compare/1.0.0...HEAD -[1.1.0]: ../../compare/1.0.6...1.1.0 +[2.0.0]: ../../compare/1.0.6...1.2.0 [1.0.6]: ../../compare/1.0.5...1.0.6 [1.0.5]: ../../compare/1.0.4...1.0.5 [1.0.4]: ../../compare/1.0.3...1.0.4 diff --git a/Directory.Build.props b/Directory.Build.props index 7821863..652454b 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,5 +1,5 @@ - 1.1.0-rc + 2.0.0-rc \ No newline at end of file diff --git a/README.md b/README.md index e209f86..f4b72ca 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,11 @@ # Autodesk.PackageBuilder -This package is intended to build Autodesk `PackageContent.xml` and `RevitAddin.addin/InventorAddin.addin` using C# fluent API. - [![Autodesk](https://img.shields.io/badge/Autodesk-black?logo=autodesk&logoColor=white)](https://github.com/ricaun-io/Autodesk.PackageBuilder) [![AutoCAD](https://img.shields.io/badge/AutoCAD-E51050.svg)](https://github.com/ricaun-io/Autodesk.PackageBuilder) [![Revit](https://img.shields.io/badge/Revit-186BFF.svg)](https://github.com/ricaun-io/Autodesk.PackageBuilder) [![3ds Max](https://img.shields.io/badge/3ds%20Max-37A5CC.svg)](https://github.com/ricaun-io/Autodesk.PackageBuilder) -[![Maya](https://img.shields.io/badge/Maya-37A5CC.svg)](https://github.com/ricaun-io/Autodesk.PackageBuilder) [![Inventor](https://img.shields.io/badge/Inventor-DBAE03.svg)](https://github.com/ricaun-io/Autodesk.PackageBuilder) +[![Maya](https://img.shields.io/badge/Maya-37A5CC.svg)](https://github.com/ricaun-io/Autodesk.PackageBuilder) [![Navisworks](https://img.shields.io/badge/Navisworks-186BFF.svg)](https://github.com/ricaun-io/Autodesk.PackageBuilder)