Knara.SourceGenerators.DesignPatterns.Decorator
1.1.0
dotnet add package Knara.SourceGenerators.DesignPatterns.Decorator --version 1.1.0
NuGet\Install-Package Knara.SourceGenerators.DesignPatterns.Decorator -Version 1.1.0
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Knara.SourceGenerators.DesignPatterns.Decorator" Version="1.1.0" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Knara.SourceGenerators.DesignPatterns.Decorator" Version="1.1.0" />
<PackageReference Include="Knara.SourceGenerators.DesignPatterns.Decorator" />
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Knara.SourceGenerators.DesignPatterns.Decorator --version 1.1.0
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
#r "nuget: Knara.SourceGenerators.DesignPatterns.Decorator, 1.1.0"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Knara.SourceGenerators.DesignPatterns.Decorator@1.1.0
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Knara.SourceGenerators.DesignPatterns.Decorator&version=1.1.0
#tool nuget:?package=Knara.SourceGenerators.DesignPatterns.Decorator&version=1.1.0
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
Decorator Factory Generator
A C# source generator that automatically creates fluent factory methods for the Decorator design pattern.
Features
- Automatic Factory Generation: Creates fluent factory classes for interfaces marked with
[GenerateDecoratorFactory] - Type-Safe Decorator Chaining: Compile-time safety with IntelliSense support
- Flexible Constructor Injection: Supports decorators with varying constructor parameters
- Clean Fluent API: Method chaining for readable decorator composition
Quick Start
Add the source generator to your project:
<ItemGroup> <ProjectReference Include="path/to/Knara.SourceGenerators.DesignPatterns.Decorator.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" /> </ItemGroup>
Or via NuGet (when published):
dotnet add package Knara.SourceGenerators.DesignPatterns.Decorator
If you are using the generator in .net 4.+ projects, refer to this guide for additional steps.
1. Mark Your Interface
Add the [GenerateDecoratorFactory] attribute to your service interface:
[GenerateDecoratorFactory(BaseName = "User")]
public interface IUserService
{
Task<User> GetUserByIdAsync(int userId);
Task<List<User>> GetAllUsersAsync();
Task CreateUserAsync(User user);
Task UpdateUserAsync(User user);
Task DeleteUserAsync(int userId);
}
2. Create Your Base Implementation
public class UserService : IUserService
{
public async Task<User> GetUserByIdAsync(int userId)
{
// Simulate database call await Task.Delay(100);
return new User { Id = userId, Email = "user@example.com" };
}
// ... other methods
}
3. Create Decorators
Each decorator should implement the interface and be marked with [Decorator]:
[Decorator(Type = "Logging")]
public class UserLoggingDecorator : IUserService
{
private readonly IUserService _inner;
private readonly ILogger<IUserService> _logger;
public UserLoggingDecorator(IUserService inner, ILogger<IUserService> logger)
{
_inner = inner;
_logger = logger;
}
public async Task<User> GetUserByIdAsync(int userId)
{
_logger.LogInformation($"Getting user by ID: {userId}");
var user = await _inner.GetUserByIdAsync(userId);
_logger.LogInformation($"Retrieved user: {user.Email}");
return user;
}
// ... other methods
}
4. Use the Generated Factory
// Create decorated service using the generated factory
IUserService userService = UserDecoratorFactory
.Create(new UserService())
.WithValidation()
.WithCaching(cache)
.WithLogging(logger);
// Use the service normally
var user = await userService.GetUserByIdAsync(1);
Generated Factory Code
For the IUserService interface, the generator creates:
// <auto-generated /> #nullable enable
namespace Demo.Decorator.ConsoleApp;
public static class UserDecoratorFactory
{
public static IUserService Create(IUserService implementation)
{
return implementation;
}
public static IUserService WithLogging(this IUserService service, ILogger<IUserService> logger)
{
return new UserLoggingDecorator(service, logger);
}
public static IUserService WithCaching(this IUserService service, IMemoryCache cache)
{
return new UserCachingDecorator(service, cache);
}
public static IUserService WithValidation(this IUserService service)
{
return new UserValidationDecorator(service);
}
public static IUserService WithPerformanceMonitoring(this IUserService service, ILogger<UserPerformanceMonitoringDecorator> logger)
{
return new UserPerformanceMonitoringDecorator(service, logger);
}
}
Dependency Injection Integration
public static IServiceCollection DependencyInjectionUsage(this IServiceCollection services)
{
services.AddScoped<IUserService>(provider =>
{
var implementation = new UserService();
var logger = provider.GetRequiredService<ILogger<UserService>>();
var performanceLogger = provider.GetRequiredService<ILogger<UserPerformanceMonitoringDecorator>>();
var cache = provider.GetRequiredService<IMemoryCache>();
return UserDecoratorFactory
.Create(implementation)
.WithValidation()
.WithCaching(cache)
.WithPerformanceMonitoring(performanceLogger)
.WithLogging(logger);
});
return services;
}
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
-
.NETStandard 2.0
- Microsoft.CodeAnalysis.CSharp (>= 4.14.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.