Nextended.CodeGen
Compile-time source code generation from various sources including classes, JSON, XML, and Excel files.
Overview
Nextended.CodeGen is a Roslyn source generator that automatically generates code at compile-time. It supports DTO generation from attributes, class generation from JSON/XML structures, and model generation from Excel spreadsheets.
Note: This package is in early testing stage. The API may change in future releases.
Installation
dotnet add package Nextended.CodeGen
dotnet add package Nextended.Core
Key Features
1. DTO Generation from Attributes
Automatically generate Data Transfer Objects (DTOs) from your domain classes.
using Nextended.Core.Attributes;
[AutoGenerateDto(
ToDtoMethodName = "ToDto",
ToSourceMethodName = "ToEntity",
IsComCompatible = true,
Namespace = "MyApp.Dtos"
)]
public class User
{
public int Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public string Password { get; set; } // Can be excluded in DTO
}
Generated DTO:
namespace MyApp.Dtos
{
public class UserDto
{
public int Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
}
}
2. Class Generation from JSON/XML
Generate strongly-typed classes from configuration files or API responses.
// appsettings.json
{
"Database": {
"ConnectionString": "Server=localhost;...",
"MaxPoolSize": 100
},
"Api": {
"BaseUrl": "https://api.example.com",
"Timeout": 30
}
}
Configuration:
{
"StructureGenerations": [
{
"SourceFile": "/Sources/appsettings.json",
"RootClassName": "ServerConfiguration",
"Namespace": "MyApp.Configuration"
}
]
}
Generated class:
namespace MyApp.Configuration
{
public class ServerConfiguration
{
public Database Database { get; set; }
public Api Api { get; set; }
}
public class Database
{
public string ConnectionString { get; set; }
public int MaxPoolSize { get; set; }
}
public class Api
{
public string BaseUrl { get; set; }
public int Timeout { get; set; }
}
}
3. Excel to Class Generation
Generate data classes and static lookup tables from Excel spreadsheets.
{
"ExcelGenerations": [
{
"ModelType": "RecordStruct",
"SourceFile": "/Sources/countries.xlsx",
"Namespace": "MyApp.Data",
"RootClassName": "Country",
"KeyColumn": "A",
"HeaderRowIndex": 1,
"DataStartRowIndex": 2,
"GenerateModelClass": true,
"GenerateStaticTable": true,
"StaticClassName": "Countries",
"GenerateAllCollection": true
}
]
}
Configuration
Project Setup
- Add packages to your
.csproj:
<ItemGroup>
<PackageReference Include="Nextended.CodeGen" Version="9.0.15" />
<PackageReference Include="Nextended.Core" Version="9.0.15" PrivateAssets="all" GeneratePathProperty="true" />
</ItemGroup>
- Create
CodeGen.config.json:
{
"DtoGeneration": {
"ComIdClassName": "ComGuids",
"ComIdClassPropertyFormat": "Id{0}",
"ComIdClassModifier": "Public",
"OneFilePerClass": true,
"CreateRegions": true,
"CreateComments": true,
"GeneratePartial": true,
"Namespace": "MyApp.Generated",
"Suffix": "Dto"
},
"StructureGenerations": [
{
"SourceFile": "/Sources/appsettings.json",
"RootClassName": "AppSettings",
"Namespace": "MyApp.Configuration"
}
]
}
- Add config file to
.csproj:
<ItemGroup>
<AdditionalFiles Include="CodeGen.config.json" />
</ItemGroup>
Usage Examples
Basic DTO Generation
using Nextended.Core.Attributes;
[AutoGenerateDto]
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
public DateTime CreatedDate { get; set; }
}
// Usage after build
var product = new Product
{
Id = 1,
Name = "Widget",
Price = 99.99m
};
var dto = product.ToDto(); // Generated extension method
var backToEntity = dto.ToEntity(); // Round-trip conversion
Advanced DTO Configuration
[AutoGenerateDto(
Suffix = "Dto",
Prefix = null,
ToDtoMethodName = "ToTransferObject",
ToSourceMethodName = "ToModel",
Namespace = "MyApp.Dtos",
IsComCompatible = true,
GeneratePartial = true
)]
public class Order
{
public int Id { get; set; }
public string OrderNumber { get; set; }
public List<OrderItem> Items { get; set; }
public Customer Customer { get; set; }
[IgnoreInDto]
public string InternalNotes { get; set; }
}
Configuration from JSON
appsettings.json:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning"
}
},
"ConnectionStrings": {
"DefaultConnection": "Server=localhost;Database=MyDb;..."
},
"Features": {
"EnableCache": true,
"MaxRetries": 3
}
}
CodeGen.config.json:
{
"StructureGenerations": [
{
"SourceFile": "/Sources/appsettings.json",
"RootClassName": "AppConfiguration",
"Namespace": "MyApp.Config",
"Ignore": ["Logging.LogLevel.Microsoft"]
}
]
}
Usage:
var config = new AppConfiguration();
var connectionString = config.ConnectionStrings.DefaultConnection;
Excel Data Generation
Excel file structure: | Code | Name | Country | Active | |——|——|———|——–| | US | United States | USA | Yes | | UK | United Kingdom | GBR | Yes | | CA | Canada | CAN | Yes |
Configuration:
{
"ExcelGenerations": [
{
"SourceFile": "/Sources/locations.xlsx",
"Namespace": "MyApp.Data",
"RootClassName": "Location",
"KeyColumn": "A",
"StaticClassName": "Locations",
"GenerateStaticTable": true,
"ColumnMappings": {
"Code": "LocationCode",
"Name": "LocationName"
}
}
]
}
Generated code:
public record struct Location
{
public string LocationCode { get; init; }
public string LocationName { get; init; }
public string Country { get; init; }
public string Active { get; init; }
}
public static class Locations
{
public static Location US => new()
{
LocationCode = "US",
LocationName = "United States",
Country = "USA",
Active = "Yes"
};
public static Location UK => new()
{
LocationCode = "UK",
LocationName = "United Kingdom",
Country = "GBR",
Active = "Yes"
};
public static IReadOnlyList<Location> All { get; } = new[]
{
US, UK, CA
};
}
Usage:
var usLocation = Locations.US;
var allLocations = Locations.All;
Detailed Generation Examples
JSON Structure Generation
Generate strongly-typed classes from JSON files such as configuration files, API responses, or data schemas.
Example 1: Application Configuration
Source File: appsettings.json
{
"Database": {
"ConnectionString": "Server=localhost;Database=MyApp;",
"Timeout": 30,
"MaxRetryCount": 3
},
"Redis": {
"Host": "localhost",
"Port": 6379,
"DefaultDatabase": 0
},
"Security": {
"JwtSecret": "your-secret-key",
"TokenExpirationMinutes": 60,
"EnableTwoFactor": true
},
"Features": {
"EnableCache": true,
"EnableLogging": true,
"MaxUploadSizeMB": 10
}
}
Configuration: CodeGen.config.json
{
"StructureGenerations": [
{
"SourceFile": "/Sources/appsettings.json",
"RootClassName": "ApplicationSettings",
"Namespace": "MyApp.Configuration",
"Prefix": "App",
"OutputPath": "./Generated/Configuration/"
}
]
}
Generated Classes:
namespace MyApp.Configuration
{
public class AppApplicationSettings
{
public Database Database { get; set; }
public Redis Redis { get; set; }
public Security Security { get; set; }
public Features Features { get; set; }
}
public class Database
{
public string ConnectionString { get; set; }
public int Timeout { get; set; }
public int MaxRetryCount { get; set; }
}
public class Redis
{
public string Host { get; set; }
public int Port { get; set; }
public int DefaultDatabase { get; set; }
}
public class Security
{
public string JwtSecret { get; set; }
public int TokenExpirationMinutes { get; set; }
public bool EnableTwoFactor { get; set; }
}
public class Features
{
public bool EnableCache { get; set; }
public bool EnableLogging { get; set; }
public int MaxUploadSizeMB { get; set; }
}
}
Usage:
using MyApp.Configuration;
// Use the generated strongly-typed configuration
var settings = new AppApplicationSettings
{
Database = new Database
{
ConnectionString = "...",
Timeout = 30
}
};
// Access with IntelliSense support
var timeout = settings.Database.Timeout;
var enableCache = settings.Features.EnableCache;
Example 2: API Response Schema
Source File: user-api-response.json
{
"user": {
"id": 123,
"username": "john_doe",
"email": "john@example.com",
"profile": {
"firstName": "John",
"lastName": "Doe",
"avatar": "https://example.com/avatar.jpg",
"bio": "Software Developer"
},
"settings": {
"notifications": {
"email": true,
"push": false,
"sms": true
},
"privacy": {
"profileVisible": true,
"showEmail": false
}
},
"metadata": {
"createdAt": "2024-01-01T00:00:00Z",
"lastLogin": "2024-06-15T10:30:00Z",
"accountStatus": "active"
}
}
}
Configuration:
{
"StructureGenerations": [
{
"SourceFile": "/Sources/user-api-response.json",
"RootClassName": "UserApiResponse",
"Namespace": "MyApp.ApiModels",
"Ignore": ["metadata.lastLogin"]
}
]
}
Generated Classes:
namespace MyApp.ApiModels
{
public class UserApiResponse
{
public User User { get; set; }
}
public class User
{
public int Id { get; set; }
public string Username { get; set; }
public string Email { get; set; }
public Profile Profile { get; set; }
public Settings Settings { get; set; }
public Metadata Metadata { get; set; }
}
public class Profile
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Avatar { get; set; }
public string Bio { get; set; }
}
public class Settings
{
public Notifications Notifications { get; set; }
public Privacy Privacy { get; set; }
}
public class Notifications
{
public bool Email { get; set; }
public bool Push { get; set; }
public bool Sms { get; set; }
}
public class Privacy
{
public bool ProfileVisible { get; set; }
public bool ShowEmail { get; set; }
}
public class Metadata
{
public string CreatedAt { get; set; }
public string AccountStatus { get; set; }
}
}
XML Structure Generation
Generate classes from XML files using the same configuration structure.
Source File: config.xml
<?xml version="1.0" encoding="utf-8"?>
<Configuration>
<Server>
<Host>localhost</Host>
<Port>8080</Port>
<EnableSSL>true</EnableSSL>
</Server>
<Logging>
<Level>Information</Level>
<FilePath>./logs/app.log</FilePath>
<MaxFileSizeMB>50</MaxFileSizeMB>
</Logging>
</Configuration>
Configuration:
{
"StructureGenerations": [
{
"SourceFile": "/Sources/config.xml",
"RootClassName": "ServerConfiguration",
"Namespace": "MyApp.XmlConfig"
}
]
}
Generated Classes:
namespace MyApp.XmlConfig
{
public class ServerConfiguration
{
public Server Server { get; set; }
public Logging Logging { get; set; }
}
public class Server
{
public string Host { get; set; }
public int Port { get; set; }
public bool EnableSSL { get; set; }
}
public class Logging
{
public string Level { get; set; }
public string FilePath { get; set; }
public int MaxFileSizeMB { get; set; }
}
}
Excel Generation (Advanced)
Generate data models and static lookup tables from Excel spreadsheets. This is particularly useful for reference data, lookup tables, and configuration data.
Example 1: Country/Region Codes
Excel File Structure: countries.xlsx
| Code | Name | ISO3 | NumericCode | PhonePrefix | Capital |
|---|---|---|---|---|---|
| US | United States | USA | 840 | +1 | Washington, D.C. |
| GB | United Kingdom | GBR | 826 | +44 | London |
| DE | Germany | DEU | 276 | +49 | Berlin |
| JP | Japan | JPN | 392 | +81 | Tokyo |
| CA | Canada | CAN | 124 | +1 | Ottawa |
Configuration:
{
"ExcelGenerations": [
{
"ModelType": "RecordStruct",
"SourceFile": "/Sources/countries.xlsx",
"SheetName": null,
"Namespace": "MyApp.Data.Geography",
"RootClassName": "Country",
"KeyColumn": "A",
"HeaderRowIndex": 1,
"DataStartRowIndex": 2,
"GenerateModelClass": true,
"GenerateStaticTable": true,
"StaticClassName": "Countries",
"GenerateAllCollection": true,
"ColumnMappings": {
"Code": "IsoCode",
"ISO3": "Iso3Code"
},
"PropertyTypeOverrides": {
"NumericCode": "int",
"PhonePrefix": "string"
}
}
]
}
Generated Code:
namespace MyApp.Data.Geography
{
// Model class
public record struct Country
{
public string IsoCode { get; init; }
public string Name { get; init; }
public string Iso3Code { get; init; }
public int NumericCode { get; init; }
public string PhonePrefix { get; init; }
public string Capital { get; init; }
}
// Static lookup table
public static class Countries
{
public static Country US => new Country
{
IsoCode = "US",
Name = "United States",
Iso3Code = "USA",
NumericCode = 840,
PhonePrefix = "+1",
Capital = "Washington, D.C."
};
public static Country GB => new Country
{
IsoCode = "GB",
Name = "United Kingdom",
Iso3Code = "GBR",
NumericCode = 826,
PhonePrefix = "+44",
Capital = "London"
};
public static Country DE => new Country
{
IsoCode = "DE",
Name = "Germany",
Iso3Code = "DEU",
NumericCode = 276,
PhonePrefix = "+49",
Capital = "Berlin"
};
// ... more countries
public static IReadOnlyList<Country> All { get; } = new[]
{
US, GB, DE, JP, CA
};
public static Country GetByCode(string code)
{
return All.FirstOrDefault(c => c.IsoCode == code);
}
}
}
Usage:
using MyApp.Data.Geography;
// Access individual countries
var usa = Countries.US;
Console.WriteLine($"{usa.Name} - {usa.PhonePrefix}");
// Get all countries
var allCountries = Countries.All;
foreach (var country in allCountries)
{
Console.WriteLine($"{country.Name} ({country.IsoCode})");
}
// Lookup by code
var germany = Countries.GetByCode("DE");
Example 2: Product Categories with Hierarchies
Excel File: product-categories.xlsx
| CategoryId | CategoryName | ParentId | SortOrder | Active | Description |
|---|---|---|---|---|---|
| 1 | Electronics | 1 | Y | Electronic devices and accessories | |
| 2 | Computers | 1 | 1 | Y | Desktop and laptop computers |
| 3 | Laptops | 2 | 1 | Y | Portable computers |
| 4 | Desktops | 2 | 2 | Y | Desktop computers |
| 5 | Smartphones | 1 | 2 | Y | Mobile phones |
Configuration:
{
"ExcelGenerations": [
{
"ModelType": "Class",
"SourceFile": "/Sources/product-categories.xlsx",
"Namespace": "MyApp.Catalog",
"RootClassName": "ProductCategory",
"KeyColumn": "A",
"HeaderRowIndex": 1,
"DataStartRowIndex": 2,
"GenerateModelClass": true,
"GenerateStaticTable": true,
"StaticClassName": "ProductCategories",
"GenerateAllCollection": true,
"PropertyTypeOverrides": {
"CategoryId": "int",
"ParentId": "int?",
"SortOrder": "int",
"Active": "bool"
},
"ColumnMappings": {
"Active": "IsActive"
}
}
]
}
Generated Classes:
namespace MyApp.Catalog
{
public class ProductCategory
{
public int CategoryId { get; set; }
public string CategoryName { get; set; }
public int? ParentId { get; set; }
public int SortOrder { get; set; }
public bool IsActive { get; set; }
public string Description { get; set; }
}
public static class ProductCategories
{
public static ProductCategory Electronics => new ProductCategory
{
CategoryId = 1,
CategoryName = "Electronics",
ParentId = null,
SortOrder = 1,
IsActive = true,
Description = "Electronic devices and accessories"
};
public static ProductCategory Computers => new ProductCategory
{
CategoryId = 2,
CategoryName = "Computers",
ParentId = 1,
SortOrder = 1,
IsActive = true,
Description = "Desktop and laptop computers"
};
// ... more categories
public static IReadOnlyList<ProductCategory> All { get; } = new[]
{
Electronics,
Computers,
Laptops,
Desktops,
Smartphones
};
public static ProductCategory GetById(int id)
{
return All.FirstOrDefault(c => c.CategoryId == id);
}
public static IEnumerable<ProductCategory> GetChildren(int parentId)
{
return All.Where(c => c.ParentId == parentId);
}
}
}
Usage:
using MyApp.Catalog;
// Get root categories
var rootCategories = ProductCategories.All
.Where(c => c.ParentId == null);
// Get children of Electronics
var electronicsChildren = ProductCategories.GetChildren(1);
// Build category tree
var category = ProductCategories.Computers;
Console.WriteLine($"{category.CategoryName}: {category.Description}");
Excel Generation Configuration Options
| Property | Type | Description |
|---|---|---|
| ModelType | string | Type of model to generate: Class, Struct, Record, RecordStruct |
| SourceFile | string | Path to the Excel file (relative to project root) |
| SheetName | string? | Specific sheet name. If null, uses first sheet |
| Namespace | string | Namespace for generated classes |
| RootClassName | string | Name of the model class |
| KeyColumn | string | Column letter to use as key (e.g., “A”, “B”) |
| HeaderRowIndex | int | Row number containing column headers (1-based) |
| DataStartRowIndex | int | First row containing data (1-based) |
| GenerateModelClass | bool | Whether to generate the model class |
| GenerateStaticTable | bool | Whether to generate static lookup class |
| StaticClassName | string | Name of the static lookup class |
| GenerateAllCollection | bool | Whether to generate All property with all records |
| ColumnMappings | object | Dictionary mapping Excel column names to property names |
| PropertyTypeOverrides | object | Dictionary specifying custom types for properties |
| OutputPath | string? | Custom output path for generated files |
Tips for Excel Generation
-
Column Headers: Use clear, descriptive names in the header row. These become property names.
- Data Types: By default, all columns are strings. Use
PropertyTypeOverridesto specify correct types:"PropertyTypeOverrides": { "Id": "int", "Price": "decimal", "IsActive": "bool", "CreatedDate": "DateTime" } - Naming: Use
ColumnMappingsto rename columns that don’t follow C# naming conventions:"ColumnMappings": { "Full Name": "FullName", "E-Mail": "Email", "ZIP Code": "PostalCode" } - Model Types:
RecordStruct: Immutable, value type, best for small lookup dataRecord: Immutable, reference type, good for DTOsClass: Mutable, reference type, most flexibleStruct: Mutable, value type, for small data structures
- Key Column: Choose a unique identifier column (usually first column) for generating property accessors.
AutoGenerateDto Attribute Reference
The AutoGenerateDto attribute is applied to classes or enums to generate DTOs at compile-time.
Basic Usage
[AutoGenerateDto]
public class User
{
public int Id { get; set; }
public string Name { get; set; }
}
// Generates: UserDto class with mapping methods
Attribute Properties
Namespace and Naming
| Property | Type | Default | Description |
|---|---|---|---|
Namespace | string | null | Target namespace for generated DTO. If null, uses source class namespace |
Prefix | string | ”” | Prefix for generated class name (e.g., “Com” → “ComUserDto”) |
Suffix | string | “Dto” | Suffix for generated class name (e.g., “Dto” → “UserDto”) |
GeneratedClassName | string | null | Override complete class name. Ignores prefix/suffix if set |
Example:
[AutoGenerateDto(
Namespace = "MyApp.Api.Dtos",
Prefix = "Api",
Suffix = "Response"
)]
public class User { }
// Generates: MyApp.Api.Dtos.ApiUserResponse
Mapping Configuration
| Property | Type | Default | Description |
|---|---|---|---|
GenerateMapping | bool | true | Generate extension methods for mapping (ToDto/ToSource) |
ToDtoMethodName | string | null | Name of the method to convert source to DTO (e.g., “ToDto”) |
ToSourceMethodName | string | null | Name of the method to convert DTO back to source (e.g., “ToEntity”) |
Example:
[AutoGenerateDto(
ToDtoMethodName = "ToApiModel",
ToSourceMethodName = "ToEntity"
)]
public class User { }
// Usage:
var dto = user.ToApiModel();
var entity = dto.ToEntity();
Property Control
| Property | Type | Default | Description |
|---|---|---|---|
PropertiesToIgnore | string[] | null | Property names to exclude from DTO generation |
Example:
[AutoGenerateDto(PropertiesToIgnore = new[] { "Password", "InternalId" })]
public class User
{
public int Id { get; set; }
public string Name { get; set; }
public string Password { get; set; } // Not included in DTO
public Guid InternalId { get; set; } // Not included in DTO
}
Alternative: Use [IgnoreOnGeneration] attribute on properties:
public class User
{
public int Id { get; set; }
[IgnoreOnGeneration]
public string Password { get; set; } // Not included in DTO
}
Inheritance and Interfaces
| Property | Type | Default | Description |
|---|---|---|---|
BaseType | string | null | Base type for generated DTO (e.g., “BaseDto”) |
Interfaces | string[] | null | Interfaces to implement (e.g., “IDto”, “IValidatable”) |
AutoGenerateDerived | bool | false | Automatically generate DTOs for derived classes |
Example:
[AutoGenerateDto(
BaseType = "EntityBase",
Interfaces = new[] { "IDto", "IAuditable" }
)]
public class User { }
// Generates:
public class UserDto : EntityBase, IDto, IAuditable
{
// Properties...
}
COM Compatibility
| Property | Type | Default | Description |
|---|---|---|---|
IsComCompatible | bool | false | Generate COM-visible and COM-compatible code with GUIDs |
Example:
[AutoGenerateDto(IsComCompatible = true)]
public class User { }
// Generates:
[ComVisible(true)]
[Guid("...")]
public class UserDto
{
// Properties...
}
Modifiers and Access
| Property | Type | Default | Description |
|---|---|---|---|
ClassModifier | Modifier | Public | Access modifier for generated class (Public, Internal, Private) |
InterfaceModifier | Modifier | Public | Access modifier for generated interface |
DefaultPropertyInterfaceAccess | InterfaceProperty | GetSet | Default property access in interface (Get, Set, GetSet) |
Example:
[AutoGenerateDto(
ClassModifier = Modifier.Internal,
InterfaceModifier = Modifier.Public
)]
public class User { }
Attributes and Metadata
| Property | Type | Default | Description |
|---|---|---|---|
KeepAttributesOnGeneratedClass | bool | false | Copy attributes from source class to DTO |
KeepAttributesOnGeneratedInterface | bool | false | Copy attributes from source class to generated interface |
KeepPropertyAttributesOnGeneratedClass | bool | false | Copy property attributes to DTO properties |
KeepPropertyAttributesOnGeneratedInterface | bool | false | Copy property attributes to interface properties |
PreClassString | string | null | String to add before class (e.g., attributes) |
PreInterfaceString | string | null | String to add before interface (e.g., attributes) |
Example:
[AutoGenerateDto(
PreClassString = "[Serializable]\n[JsonObject]",
KeepPropertyAttributesOnGeneratedClass = true
)]
public class User
{
[Required]
[StringLength(100)]
public string Name { get; set; }
}
// Generates:
[Serializable]
[JsonObject]
public class UserDto
{
[Required]
[StringLength(100)]
public string Name { get; set; }
}
Namespaces and Using Directives
| Property | Type | Default | Description |
|---|---|---|---|
Usings | string[] | null | Additional using directives |
AddReferencedNamespacesUsings | bool | false | Add usings for all referenced namespaces |
AddContainingNamespaceUsings | bool | false | Add using for source class namespace |
Example:
[AutoGenerateDto(
Usings = new[] { "System.ComponentModel.DataAnnotations", "MyApp.Helpers" },
AddReferencedNamespacesUsings = true
)]
public class User { }
Complete Example
using Nextended.Core.Attributes;
using Nextended.Core.Enums;
[AutoGenerateDto(
// Naming
Namespace = "MyApp.Api.Dtos",
Suffix = "Response",
// Mapping
ToDtoMethodName = "ToApiResponse",
ToSourceMethodName = "ToEntity",
// Inheritance
BaseType = "BaseResponse",
Interfaces = new[] { "IApiResponse" },
// Properties
PropertiesToIgnore = new[] { "PasswordHash", "InternalData" },
// Modifiers
ClassModifier = Modifier.Public,
// Attributes
KeepPropertyAttributesOnGeneratedClass = true,
PreClassString = "[Serializable]",
// Namespaces
Usings = new[] { "System.ComponentModel.DataAnnotations" }
)]
public class User
{
public int Id { get; set; }
[Required]
[StringLength(100)]
public string Username { get; set; }
[EmailAddress]
public string Email { get; set; }
[IgnoreOnGeneration]
public string PasswordHash { get; set; }
public DateTime CreatedAt { get; set; }
}
// Usage:
var user = GetUser();
var response = user.ToApiResponse();
var userAgain = response.ToEntity();
Configuration Options
DtoGeneration Options (CodeGen.config.json)
These settings apply to all DTOs unless overridden by attribute properties.
| Option | Type | Description |
|---|---|---|
Namespace | string | Default namespace for generated DTOs |
Suffix | string | Default suffix for DTO class names (default: “Dto”) |
Prefix | string | Default prefix for DTO class names |
ToDtoMethodName | string | Default name of ToDto extension method |
ToSourceMethodName | string | Default name of ToSource extension method |
IsComCompatible | bool | Generate COM-compatible GUIDs by default |
GeneratePartial | bool | Generate as partial classes (default: true) |
OneFilePerClass | bool | Create separate file per DTO (default: true) |
CreateRegions | bool | Add region blocks (default: true) |
CreateComments | bool | Add XML comments (default: true) |
ComIdClassName | string | Name of the class for COM GUIDs |
ComIdClassPropertyFormat | string | Format for COM ID properties |
ComIdClassModifier | string | Modifier for COM ID class |
BaseType | string | Default base type for DTOs |
Interfaces | string[] | Default interfaces for DTOs |
Usings | string[] | Default using directives |
KeepAttributesOnGeneratedClass | bool | Copy attributes from source classes |
KeepAttributesOnGeneratedInterface | bool | Copy attributes to interfaces |
AddReferencedNamespacesUsings | bool | Add usings for referenced namespaces |
AddContainingNamespaceUsings | bool | Add using for source namespaces |
PreInterfaceString | string | String before generated interfaces |
PreClassString | string | String before generated classes |
DefaultMappingSettings | object | Default mapping settings configuration |
OutputPath | string | Output directory for generated files |
StructureGeneration Options (JSON/XML)
Complete reference for generating classes from JSON and XML files.
| Option | Type | Required | Description |
|---|---|---|---|
SourceFile | string | Yes | Path to JSON or XML source file (relative to project root) |
RootClassName | string | Yes | Name of the root generated class |
Namespace | string | Yes | Target namespace for generated classes |
Prefix | string | No | Prefix for all generated class names |
Suffix | string | No | Suffix for all generated class names |
Ignore | string[] | No | Property paths to ignore (e.g., “Database.Password”) |
OutputPath | string | No | Output directory for generated files (if null, added to compilation) |
JSON Generation Examples
Basic Configuration File:
appsettings.json:
{
"Database": {
"ConnectionString": "Server=localhost;Database=MyDb;",
"MaxPoolSize": 100,
"EnableLogging": true
},
"Api": {
"BaseUrl": "https://api.example.com",
"Timeout": 30,
"ApiKey": "secret-key"
}
}
Configuration:
{
"StructureGenerations": [
{
"SourceFile": "/Config/appsettings.json",
"RootClassName": "AppSettings",
"Namespace": "MyApp.Configuration"
}
]
}
Generated Code:
namespace MyApp.Configuration
{
public class AppSettings
{
public Database Database { get; set; }
public Api Api { get; set; }
}
public class Database
{
public string ConnectionString { get; set; }
public int MaxPoolSize { get; set; }
public bool EnableLogging { get; set; }
}
public class Api
{
public string BaseUrl { get; set; }
public int Timeout { get; set; }
public string ApiKey { get; set; }
}
}
Usage:
var config = new AppSettings
{
Database = new Database
{
ConnectionString = "...",
MaxPoolSize = 100
}
};
Advanced with Ignore:
{
"StructureGenerations": [
{
"SourceFile": "/Config/appsettings.json",
"RootClassName": "AppSettings",
"Namespace": "MyApp.Configuration",
"Prefix": "Cfg",
"Ignore": ["Api.ApiKey", "Database.ConnectionString"],
"OutputPath": "./Generated/Config/"
}
]
}
Complex JSON Structure:
users.json:
{
"users": [
{
"id": 1,
"name": "John Doe",
"email": "john@example.com",
"roles": ["admin", "user"],
"metadata": {
"lastLogin": "2024-01-15T10:30:00Z",
"loginCount": 42
}
}
],
"pagination": {
"page": 1,
"pageSize": 10,
"total": 100
}
}
Generated Classes:
public class UsersRoot
{
public List<User> Users { get; set; }
public Pagination Pagination { get; set; }
}
public class User
{
public int Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public List<string> Roles { get; set; }
public Metadata Metadata { get; set; }
}
public class Metadata
{
public DateTime LastLogin { get; set; }
public int LoginCount { get; set; }
}
public class Pagination
{
public int Page { get; set; }
public int PageSize { get; set; }
public int Total { get; set; }
}
XML Generation Examples
Simple XML Configuration:
<!-- config.xml -->
<Configuration>
<Server>
<Host>localhost</Host>
<Port>8080</Port>
<UseSSL>true</UseSSL>
</Server>
<Logging>
<Level>Information</Level>
<FilePath>logs/app.log</FilePath>
</Logging>
</Configuration>
Configuration:
{
"StructureGenerations": [
{
"SourceFile": "/Config/config.xml",
"RootClassName": "Configuration",
"Namespace": "MyApp.Config"
}
]
}
Generated Code:
namespace MyApp.Config
{
public class Configuration
{
public Server Server { get; set; }
public Logging Logging { get; set; }
}
public class Server
{
public string Host { get; set; }
public int Port { get; set; }
public bool UseSSL { get; set; }
}
public class Logging
{
public string Level { get; set; }
public string FilePath { get; set; }
}
}
ExcelGeneration Options
Complete reference for generating classes from Excel spreadsheets.
| Option | Type | Required | Description |
|---|---|---|---|
SourceFile | string | Yes | Path to Excel file (.xlsx, .xls) |
SheetName | string | No | Specific sheet name (null for first sheet) |
Namespace | string | Yes | Target namespace for generated classes |
RootClassName | string | Yes | Name of the model/record class |
StaticClassName | string | No | Name of the static lookup class |
KeyColumn | string | No | Column letter to use as key (e.g., “A”, “B”) |
HeaderRowIndex | int | Yes | Row number containing column headers (1-based) |
DataStartRowIndex | int | Yes | First row number containing data (1-based) |
ModelType | string | No | Type of model: “Class”, “RecordClass”, “RecordStruct” (default: “Class”) |
GenerateModelClass | bool | No | Generate the model/record class (default: true) |
GenerateStaticTable | bool | No | Generate static lookup class with data (default: false) |
GenerateAllCollection | bool | No | Generate collection of all records (default: false) |
ColumnMappings | Dictionary<string,string> | No | Map Excel column names to property names |
PropertyTypeOverrides | Dictionary<string,string> | No | Override property types |
OutputPath | string | No | Output directory for generated files |
Excel Generation Examples
Example 1: Simple Data Table
Excel File (countries.xlsx):
| Code | Name | Population | Capital |
|------|----------------|------------|------------|
| US | United States | 331000000 | Washington |
| UK | United Kingdom | 67000000 | London |
| FR | France | 65000000 | Paris |
Configuration:
{
"ExcelGenerations": [
{
"SourceFile": "/Data/countries.xlsx",
"Namespace": "MyApp.Data",
"RootClassName": "Country",
"HeaderRowIndex": 1,
"DataStartRowIndex": 2,
"GenerateModelClass": true
}
]
}
Generated Code:
namespace MyApp.Data
{
public class Country
{
public string Code { get; set; }
public string Name { get; set; }
public int Population { get; set; }
public string Capital { get; set; }
}
}
Example 2: Static Lookup Table
Configuration:
{
"ExcelGenerations": [
{
"SourceFile": "/Data/countries.xlsx",
"Namespace": "MyApp.Data",
"RootClassName": "Country",
"StaticClassName": "Countries",
"KeyColumn": "A",
"HeaderRowIndex": 1,
"DataStartRowIndex": 2,
"GenerateModelClass": true,
"GenerateStaticTable": true,
"GenerateAllCollection": true
}
]
}
Generated Code:
namespace MyApp.Data
{
public class Country
{
public string Code { get; set; }
public string Name { get; set; }
public int Population { get; set; }
public string Capital { get; set; }
}
public static class Countries
{
public static Country US { get; } = new Country
{
Code = "US",
Name = "United States",
Population = 331000000,
Capital = "Washington"
};
public static Country UK { get; } = new Country
{
Code = "UK",
Name = "United Kingdom",
Population = 67000000,
Capital = "London"
};
public static Country FR { get; } = new Country
{
Code = "FR",
Name = "France",
Population = 65000000,
Capital = "Paris"
};
public static IReadOnlyList<Country> All { get; } = new[]
{
US, UK, FR
};
}
}
Usage:
// Access by key
var us = Countries.US;
Console.WriteLine($"{us.Name}: {us.Population}");
// Access all
foreach (var country in Countries.All)
{
Console.WriteLine(country.Name);
}
// Find by code
var france = Countries.All.FirstOrDefault(c => c.Code == "FR");
Example 3: Record Struct with Column Mapping
Excel File (products.xlsx):
| Product ID | Product Name | Unit Price | In Stock |
|------------|-----------------|------------|----------|
| P001 | Widget A | 19.99 | Yes |
| P002 | Gadget B | 29.99 | No |
Configuration:
{
"ExcelGenerations": [
{
"SourceFile": "/Data/products.xlsx",
"Namespace": "MyApp.Catalog",
"RootClassName": "Product",
"ModelType": "RecordStruct",
"HeaderRowIndex": 1,
"DataStartRowIndex": 2,
"ColumnMappings": {
"Product ID": "ProductId",
"Product Name": "Name",
"Unit Price": "Price",
"In Stock": "Available"
}
}
]
}
Generated Code:
namespace MyApp.Catalog
{
public record struct Product
{
public string ProductId { get; init; }
public string Name { get; init; }
public double Price { get; init; }
public string Available { get; init; }
}
}
Example 4: Custom Property Types
Excel File (locations.xlsx):
| Code | Name | Coordinates | Status | Type |
|------|-------------|------------------|---------|-----------|
| NYC | New York | 40.7128,-74.0060 | Active | Primary |
| LAX | Los Angeles | 34.0522,-118.2437| Active | Secondary |
Custom Types:
namespace MyApp.Types
{
public record struct Coordinates
{
public double Latitude { get; init; }
public double Longitude { get; init; }
public static Coordinates Parse(string value)
{
var parts = value.Split(',');
return new Coordinates
{
Latitude = double.Parse(parts[0]),
Longitude = double.Parse(parts[1])
};
}
}
public enum LocationStatus { Active, Inactive }
public enum LocationType { Primary, Secondary, Tertiary }
}
Configuration:
{
"ExcelGenerations": [
{
"SourceFile": "/Data/locations.xlsx",
"Namespace": "MyApp.Data",
"RootClassName": "Location",
"StaticClassName": "Locations",
"KeyColumn": "A",
"HeaderRowIndex": 1,
"DataStartRowIndex": 2,
"ModelType": "RecordStruct",
"GenerateStaticTable": true,
"PropertyTypeOverrides": {
"Coordinates": "MyApp.Types.Coordinates",
"Status": "MyApp.Types.LocationStatus",
"Type": "MyApp.Types.LocationType"
},
"ColumnMappings": {
"Status": "Status",
"Type": "Type"
}
}
]
}
Generated Code:
namespace MyApp.Data
{
public record struct Location
{
public string Code { get; init; }
public string Name { get; init; }
public MyApp.Types.Coordinates Coordinates { get; init; }
public MyApp.Types.LocationStatus Status { get; init; }
public MyApp.Types.LocationType Type { get; init; }
}
public static class Locations
{
public static Location NYC { get; } = new Location
{
Code = "NYC",
Name = "New York",
Coordinates = MyApp.Types.Coordinates.Parse("40.7128,-74.0060"),
Status = MyApp.Types.LocationStatus.Active,
Type = MyApp.Types.LocationType.Primary
};
public static Location LAX { get; } = new Location
{
Code = "LAX",
Name = "Los Angeles",
Coordinates = MyApp.Types.Coordinates.Parse("34.0522,-118.2437"),
Status = MyApp.Types.LocationStatus.Active,
Type = MyApp.Types.LocationType.Secondary
};
}
}
Example 5: Multiple Sheets
{
"ExcelGenerations": [
{
"SourceFile": "/Data/masterdata.xlsx",
"SheetName": "Customers",
"Namespace": "MyApp.Data",
"RootClassName": "Customer",
"HeaderRowIndex": 1,
"DataStartRowIndex": 2
},
{
"SourceFile": "/Data/masterdata.xlsx",
"SheetName": "Products",
"Namespace": "MyApp.Data",
"RootClassName": "Product",
"HeaderRowIndex": 1,
"DataStartRowIndex": 2
}
]
}
Example 6: Complete Real-World Scenario
Excel File (scac_codes.xlsx) - Shipping Carrier Codes:
| SCAC | Carrier Name | Country | Contact Email | Active |
|------|-----------------------|---------|--------------------|--------|
| ABCD | ABC Logistics | USA | info@abclog.com | Yes |
| EFGH | EFG Shipping Co | USA | contact@efg.com | Yes |
| WXYZ | WXY International | CAN | support@wxy.com | No |
Configuration:
{
"ExcelGenerations": [
{
"SourceFile": "/Sources/scac_codes.xlsx",
"SheetName": null,
"Namespace": "Shipping.Data",
"RootClassName": "ScacCode",
"StaticClassName": "ScacCodes",
"KeyColumn": "A",
"HeaderRowIndex": 1,
"DataStartRowIndex": 2,
"ModelType": "RecordStruct",
"GenerateModelClass": true,
"GenerateStaticTable": true,
"GenerateAllCollection": true,
"ColumnMappings": {
"SCAC": "Code",
"Carrier Name": "CarrierName",
"Contact Email": "Email"
},
"PropertyTypeOverrides": {
"Active": "bool"
},
"OutputPath": "./Generated/Shipping/"
}
]
}
Generated Usage:
using Shipping.Data;
// Lookup by key
var carrier = ScacCodes.ABCD;
Console.WriteLine($"Carrier: {carrier.CarrierName}");
// Search all
var activeCarriers = ScacCodes.All
.Where(c => c.Active)
.ToList();
// Use in dropdown
var dropdownItems = ScacCodes.All
.Select(c => new { Value = c.Code, Label = c.CarrierName })
.ToList();
Best Practices for Excel Generation
- Clean Headers: Use clear, descriptive column headers without special characters
- Consistent Data Types: Ensure columns contain consistent data types
- Key Columns: Use columns with unique values for
KeyColumn - Type Overrides: Use
PropertyTypeOverridesfor enums, custom types, or specific numeric types - Column Mapping: Use
ColumnMappingsto create clean property names from complex headers - Model Types:
- Use
RecordStructfor small, immutable data - Use
RecordClassfor immutable reference types - Use
Classfor mutable data that needs modification
- Use
- Output Path: Use
OutputPathto organize generated files separately from source code
Best Practices
1. Use Meaningful Names
[AutoGenerateDto(
Namespace = "MyApp.Api.Dtos",
ToDtoMethodName = "ToApiDto",
ToSourceMethodName = "ToEntity"
)]
public class User { }
2. Organize Generated Code
{
"DtoGeneration": {
"Namespace": "MyApp.Generated.Dtos",
"OutputPath": "./Generated/Dtos/",
"OneFilePerClass": true
}
}
3. Version Control Generated Files
Add to .gitignore if you regenerate on build, or commit them if you want to review changes.
4. Use Partial Classes for Customization
Generated as partial classes allow you to extend:
// Generated
public partial class UserDto
{
public int Id { get; set; }
public string Name { get; set; }
}
// Your custom code
public partial class UserDto
{
public string DisplayName => $"User: {Name}";
}
Attribute Reference
AutoGenerateDtoAttribute
The AutoGenerateDtoAttribute is the primary attribute for generating DTOs from your classes. It provides extensive configuration options to control the generated code.
Properties
Namespace Configuration
[AutoGenerateDto(Namespace = "MyApp.Dtos")]
public class User { }
Namespace (string?)
Sets the namespace for the generated DTO. If not specified, uses the configuration file default or the source class namespace with a “Dto” suffix.
Naming Configuration
[AutoGenerateDto(
Prefix = "Api",
Suffix = "Response",
GeneratedClassName = "CustomUserName" // Overrides prefix/suffix
)]
public class User { }
// Generates: ApiUserResponse or CustomUserName
Prefix (string?)
Adds a prefix to the generated class name. Default: empty string.
Suffix (string?)
Adds a suffix to the generated class name. Default: “Dto”.
GeneratedClassName (string?)
Explicitly sets the generated class name, overriding prefix and suffix logic.
Property Filtering
public class User
{
public int Id { get; set; }
public string Name { get; set; }
[IgnoreOnGeneration]
public string Password { get; set; } // Excluded from DTO
}
// Alternative: Configure in attribute
[AutoGenerateDto(PropertiesToIgnore = new[] { "Password", "InternalId" })]
public class User
{
public string Password { get; set; }
public string InternalId { get; set; }
}
PropertiesToIgnore (string[])
Array of property names to exclude from the generated DTO.
Mapping Configuration
[AutoGenerateDto(
GenerateMapping = true,
ToDtoMethodName = "ToUserDto",
ToSourceMethodName = "ToUser"
)]
public class User { }
// Usage
var user = GetUser();
var dto = user.ToUserDto();
var userAgain = dto.ToUser();
GenerateMapping (bool)
When true, generates extension methods for mapping between source and DTO. Default: true.
ToDtoMethodName (string?)
Name of the method that converts source to DTO. Default: “ToDto”.
ToSourceMethodName (string?)
Name of the method that converts DTO back to source. Default: “ToSource”.
COM Compatibility
[AutoGenerateDto(IsComCompatible = true)]
public class User { }
IsComCompatible (bool)
Generates COM-visible classes with appropriate attributes and GUIDs. Used for COM interop scenarios.
Type Configuration
[AutoGenerateDto(
BaseType = "EntityBase",
Interfaces = new[] { "IEntity", "IAuditable" }
)]
public class User { }
// Generates:
public class UserDto : EntityBase, IEntity, IAuditable { }
BaseType (string?)
Sets the base class for the generated DTO.
Interfaces (string[]?)
Adds interfaces that the generated DTO should implement.
Modifiers
[AutoGenerateDto(
ClassModifier = Modifier.Internal,
InterfaceModifier = Modifier.Public
)]
public class User { }
ClassModifier (Modifier)
Access modifier for the generated class. Options: Unset, Public, Private, Protected, Internal.
InterfaceModifier (Modifier)
Access modifier for the generated interface (if applicable).
DefaultPropertyInterfaceAccess (InterfaceProperty)
Default accessor type for interface properties. Options: Unset, GetAndSet, Get, Set.
Using Directives
[AutoGenerateDto(
Usings = new[] { "System.Text.Json.Serialization", "MyApp.CustomTypes" },
AddReferencedNamespacesUsings = true,
AddContainingNamespaceUsings = true
)]
public class User { }
Usings (string[]?)
Additional using directives to include in the generated file.
AddReferencedNamespacesUsings (bool)
Automatically includes using directives for all referenced types.
AddContainingNamespaceUsings (bool)
Includes using directive for the source class’s namespace.
Custom Code Injection
[AutoGenerateDto(
PreInterfaceString = "[JsonObject]",
PreClassString = "[Serializable]\n[DataContract]"
)]
public class User { }
// Generates:
[JsonObject]
public interface IUserDto { }
[Serializable]
[DataContract]
public class UserDto { }
PreInterfaceString (string?)
Code to insert before the generated interface declaration (e.g., attributes).
PreClassString (string?)
Code to insert before the generated class declaration (e.g., attributes).
Attribute Preservation
[AutoGenerateDto(
KeepAttributesOnGeneratedClass = true,
KeepAttributesOnGeneratedInterface = true,
KeepPropertyAttributesOnGeneratedClass = true,
KeepPropertyAttributesOnGeneratedInterface = true
)]
[DataContract]
public class User
{
[Required]
[DataMember]
public string Name { get; set; }
}
// Generated DTO keeps the attributes
[DataContract]
public class UserDto
{
[Required]
[DataMember]
public string Name { get; set; }
}
KeepAttributesOnGeneratedClass (bool)
Copies class-level attributes from source to generated class.
KeepAttributesOnGeneratedInterface (bool)
Copies class-level attributes from source to generated interface.
KeepPropertyAttributesOnGeneratedClass (bool)
Copies property-level attributes from source properties to generated class properties.
KeepPropertyAttributesOnGeneratedInterface (bool)
Copies property-level attributes from source properties to generated interface properties.
Derived Type Generation
[AutoGenerateDto(AutoGenerateDerived = true)]
public class BaseEntity { }
public class User : BaseEntity { } // DTO automatically generated
public class Product : BaseEntity { } // DTO automatically generated
AutoGenerateDerived (bool)
Automatically generates DTOs for all derived types when applied to a base class.
IgnoreOnGenerationAttribute
Use this attribute to exclude specific properties or fields from DTO generation.
public class User
{
public int Id { get; set; }
public string Name { get; set; }
[IgnoreOnGeneration]
public string Password { get; set; }
[IgnoreOnGeneration]
public byte[] PasswordHash { get; set; }
}
GenerationPropertySettingAttribute
Fine-tune individual property generation with this attribute.
public class User
{
public int Id { get; set; }
[GenerationPropertySetting(
PropertyName = "FullName", // Rename in DTO
MapWithClassMapper = true, // Use ClassMapper for conversion
InterfaceAccess = InterfaceProperty.Get, // Read-only in interface
PreClassString = "[JsonProperty(\"full_name\")]",
KeepAttributesOnGeneratedClass = true
)]
public string Name { get; set; }
}
// Generated:
public interface IUserDto
{
string FullName { get; } // Read-only
}
public class UserDto : IUserDto
{
[JsonProperty("full_name")]
public string FullName { get; set; }
}
Properties:
- PropertyName (
string?) - Custom name for the property in the generated DTO - MapWithClassMapper (
bool) - Use ClassMapper for type conversion during mapping - InterfaceAccess (
InterfaceProperty) - Property accessor type in interfaces (Get, Set, or GetAndSet) - PreInterfaceString (
string?) - Code to insert before the property in the interface - PreClassString (
string?) - Code to insert before the property in the class - KeepAttributesOnGeneratedClass (
bool) - Keep property attributes in generated class - KeepAttributesOnGeneratedInterface (
bool) - Keep property attributes in generated interface
Complete Example: Advanced DTO Generation
using Nextended.Core.Attributes;
using Nextended.Core.Enums;
namespace MyApp.Domain
{
/// <summary>
/// User entity with complete DTO generation configuration
/// </summary>
[AutoGenerateDto(
Namespace = "MyApp.Dtos",
Suffix = "Response",
ToDtoMethodName = "ToUserResponse",
ToSourceMethodName = "ToUserEntity",
GenerateMapping = true,
BaseType = "AuditableDto",
Interfaces = new[] { "IUserResponse", "IIdentifiable" },
Usings = new[] { "System.Text.Json.Serialization" },
ClassModifier = Modifier.Public,
PreClassString = "[JsonSerializable(typeof(UserResponse))]",
KeepPropertyAttributesOnGeneratedClass = true,
PropertiesToIgnore = new[] { "PasswordHash", "PasswordSalt" }
)]
public class User
{
public int Id { get; set; }
[Required]
[MaxLength(100)]
public string UserName { get; set; }
[Required]
[EmailAddress]
public string Email { get; set; }
[GenerationPropertySetting(
PropertyName = "FullName",
PreClassString = "[JsonPropertyName(\"fullName\")]"
)]
public string Name { get; set; }
[IgnoreOnGeneration]
public byte[] PasswordHash { get; set; }
[IgnoreOnGeneration]
public byte[] PasswordSalt { get; set; }
public DateTime CreatedAt { get; set; }
public DateTime? ModifiedAt { get; set; }
public List<Address> Addresses { get; set; }
}
[AutoGenerateDto(
Namespace = "MyApp.Dtos",
Suffix = "Response"
)]
public class Address
{
public string Street { get; set; }
public string City { get; set; }
public string PostalCode { get; set; }
public string Country { get; set; }
}
}
Generated result:
namespace MyApp.Dtos
{
using System;
using System.Collections.Generic;
using System.Text.Json.Serialization;
using System.ComponentModel.DataAnnotations;
[JsonSerializable(typeof(UserResponse))]
public class UserResponse : AuditableDto, IUserResponse, IIdentifiable
{
[Required]
[MaxLength(100)]
public string UserName { get; set; }
[Required]
[EmailAddress]
public string Email { get; set; }
[JsonPropertyName("fullName")]
public string FullName { get; set; }
public DateTime CreatedAt { get; set; }
public DateTime? ModifiedAt { get; set; }
public List<AddressResponse> Addresses { get; set; }
}
public class AddressResponse
{
public string Street { get; set; }
public string City { get; set; }
public string PostalCode { get; set; }
public string Country { get; set; }
}
}
Usage:
var user = await _userRepository.GetByIdAsync(userId);
var response = user.ToUserResponse();
return Ok(response);
Troubleshooting
Generated Code Not Appearing
- Ensure
CodeGen.config.jsonis marked asAdditionalFiles - Clean and rebuild:
dotnet clean && dotnet build - Check build output for generator messages
- Verify source generators are enabled in IDE
Build Errors After Generation
- Check namespace conflicts
- Verify property types are valid
- Ensure all dependencies are installed
Supported Frameworks
- .NET Standard 2.0 (Generator)
- .NET 8.0+ (Generated code)
Dependencies
- Roslyn APIs for source generation
Nextended.Corefor attributes
Related Projects
- Nextended.Core - Provides attributes and base functionality
- Nextended.AutoDto - DTO generation support
Sample Project
See the CodeGenSample project for complete examples.