Skip to content

A powerful source generator that injects code regions from template files into partial classes at compile time.

License

Notifications You must be signed in to change notification settings

RRQM/CodeInject

Repository files navigation

CodeInject - Code Region Source Generator

English | 简体中文

Build and PublishNuGet VersionNuGet Downloads

A powerful source generator that injects code regions from template files into partial classes at compile time.

✨ Features

  • 📁 Template-based code injection - Extract code regions from template files
  • 🔄 Placeholder replacement - Replace placeholders with custom values
  • 🎯 Multi-attribute support - Apply multiple injections to a single class
  • 🏗️ Nested region support - Handle nested #region blocks correctly
  • Incremental generation - Efficient compilation with minimal rebuilds

📦 Installation

Install the package via NuGet Package Manager:

dotnet add package CodeInject

Or via Package Manager Console:

Install-Package CodeInject

🚀 Quick Start

1. Create a template file

Create a template file and add it as an AdditionalFiles item in your project:

<ItemGroup> <AdditionalFilesInclude="Templates/ApiTemplate.cs" /> </ItemGroup>

Template file content:

#region ApiMethods publicasyncTask<{ReturnType}>Get{EntityName}Async(intid){// Implementation herereturnawait_repository.GetByIdAsync<{ReturnType}>(id);}publicasyncTask<{ReturnType}>Create{EntityName}Async({ReturnType} entity){// Implementation herereturnawait_repository.CreateAsync(entity);} #endregion

2. Apply the attribute

usingCodeInject;[RegionInject(FileName="Templates/ApiTemplate.cs",RegionName="ApiMethods",Placeholders=new[]{"ReturnType","User","EntityName","User"})]publicpartialclassUserService{privatereadonlyIRepository_repository;publicUserService(IRepositoryrepository){_repository=repository;}// Generated methods will be injected here automatically}

3. Generated code

The source generator will automatically create:

partialclassUserService{publicasyncTask<User>GetUserAsync(intid){// Implementation herereturnawait_repository.GetByIdAsync<User>(id);}publicasyncTask<User>CreateUserAsync(Userentity){// Implementation herereturnawait_repository.CreateAsync(entity);}}

🔧 Advanced Usage

Multiple Injections

[RegionInject(FileName="Templates/CrudTemplate.cs",RegionName="CreateMethods",Placeholders=new[]{"Entity","Product"})][RegionInject(FileName="Templates/CrudTemplate.cs",RegionName="UpdateMethods",Placeholders=new[]{"Entity","Product"})][RegionInject(FileName="Templates/ValidationTemplate.cs",RegionName="Validators",Placeholders=new[]{"Type","Product"})]publicpartialclassProductService{// Multiple code regions will be injected}

Search All Files for Region

If you don't specify the FileName, the generator will search all available files for the specified region:

[RegionInject(RegionName="CommonMethods")]publicpartialclassBaseService{// Generator will search all files for "CommonMethods" region}

Using Property Initializers

[RegionInject(FileName="Templates/ApiTemplate.cs",RegionName="ApiMethods",Placeholders=new[]{"ReturnType","Order","EntityName","Order"})]publicpartialclassOrderService{// Generated code with Order-specific implementations}

⚙️ Configuration

Project Setup

Add template files to your project as AdditionalFiles:

<ItemGroup> <AdditionalFilesInclude="Templates/**/*.cs" /> <AdditionalFilesInclude="CodeTemplates/**/*.txt" /> </ItemGroup>

Template File Format

  • Use #region RegionName and #endregion to define code blocks
  • Support for nested regions
  • Placeholders can be used in two formats:
    • {PlaceholderName} - with curly braces
    • PlaceholderName - without braces

📋 Use Cases

1. API Controller Templates

// Templates/ControllerTemplate.cs #region CrudActions [HttpGet]publicasyncTask<ActionResult<IEnumerable<{EntityType}>>>Get{EntityName}s(){ var items =await _{entityName}Service.GetAllAsync();return Ok(items);}[HttpGet("{id}")] public async Task<ActionResult<{EntityType}>> Get{EntityName}(int id){ var item =await _{entityName}Service.GetByIdAsync(id);return item ==null? NotFound(): Ok(item);}[HttpPost] public async Task<ActionResult<{EntityType}>> Create{EntityName}({EntityType}{entityName}){ var created =await _{entityName}Service.CreateAsync({entityName});return CreatedAtAction(nameof(Get{EntityName}),new{ id = created.Id }, created);} #endregion

Usage:

[RegionInject(FileName="Templates/ControllerTemplate.cs",RegionName="CrudActions",Placeholders=new[]{"EntityType","Product","EntityName","Product","entityName","product"})]publicpartialclassProductController:ControllerBase{// Generated CRUD actions will be injected here}

2. Repository Pattern Templates

// Templates/RepositoryTemplate.cs #region RepositoryMethods publicasyncTask<IEnumerable<{EntityType}>>GetAll{EntityName}sAsync(){returnawait_context.{EntityName}s.ToListAsync();} public async Task<{EntityType}> Get{EntityName}ByIdAsync(intid){returnawait_context.{EntityName}s.FindAsync(id);} public async Task<{EntityType}>Create{EntityName}Async({EntityType}entity){_context.{EntityName}s.Add(entity);await_context.SaveChangesAsync();returnentity;} #endregion

Usage:

[RegionInject(FileName="Templates/RepositoryTemplate.cs",RegionName="RepositoryMethods",Placeholders=new[]{"EntityType","User","EntityName","User"})]publicpartialclassUserRepository{// Generated repository methods will be injected here}

🔍 Diagnostics

The source generator provides the following diagnostic information:

  • CRG001: Template file not found
  • CRG002: Region not found
  • CRG003: File read error

💡 Best Practices

  1. Organize templates: Keep template files in a dedicated Templates folder
  2. Naming conventions: Use descriptive region names like CrudMethods, ValidationRules
  3. Placeholder naming: Use consistent placeholder names like EntityType, EntityName
  4. Modularization: Group related functionality into different regions
  5. Property-based syntax: Use the new property-based initialization for better readability

📋 Requirements

  • .NET Standard 2.0 or higher
  • C# 7.3 or higher
  • Visual Studio 2019 16.9+ or .NET 5.0+ SDK

🤝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

📄 License

This project is licensed under the MIT License - see the LICENSE file for details.

🆚 Comparison with Other Solutions

FeatureCodeInjectT4 TemplatesManual Coding
Compile-time generation
Incremental compilation
IDE support⚠️
Learning curveLowHighLow
FlexibilityHighHighLow

📞 Support

If you encounter any issues:

  1. Check the FAQ
  2. Search existing issues
  3. Create a new issue

⭐ If this project helps you, please give it a star!

About

A powerful source generator that injects code regions from template files into partial classes at compile time.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published