Generative.Composition
1.0.0
dotnet add package Generative.Composition --version 1.0.0
NuGet\Install-Package Generative.Composition -Version 1.0.0
<PackageReference Include="Generative.Composition" Version="1.0.0" />
<PackageVersion Include="Generative.Composition" Version="1.0.0" />
<PackageReference Include="Generative.Composition" />
paket add Generative.Composition --version 1.0.0
#r "nuget: Generative.Composition, 1.0.0"
#:package Generative.Composition@1.0.0
#addin nuget:?package=Generative.Composition&version=1.0.0
#tool nuget:?package=Generative.Composition&version=1.0.0
Introduction
Generative.Composition combines code generation and attributes to help you effectively leverage composition to follow SOLID principles.
Getting Started
Project Structure
You will need the following project types in your solution to use this library:
Source projects (code that will be read by the package)
- An attributes class library
- A model class library (decorated with attributes from your attributes class library)
- An implementation class library (decorated with attributes from your attributes class library)
An empty target class library (code will be generated and written to this project)
A console application that uses the package, reads from the source libraries and writes to the target library
Project Structure Example
Attributes
For your attributes class library, you might have a project called GenerativeWorkflow.Attributes with classes like this:
Create
[AttributeUsage(AttributeTargets.All)] public class Create : Attribute { }Delete
[AttributeUsage(AttributeTargets.All)] public class Delete : Attribute { }
Models
For your model class library, you might have a project called GenerativeWorkflow.Models with classes like this:
[Create]
[Delete]
public class Car
{
public string Model { get; set; }
public string Make { get; set; }
}
Implementation
For your implementation class library, you might have a project called GenerativeWorkflow.SourceRepository with classes like this:
RepositoryBase
public class RepositoryBase<TEntity> { protected List<TEntity> entities = new(); }Create
[Create] public class Create<TEntity> : RepositoryBase<TEntity> { public void Add(TEntity entity) { entities.Add(entity); } }Delete
[Delete] public class Delete<TEntity> : RepositoryBase<TEntity> { public void Remove(TEntity entity) { entities.Remove(entity); } }
Target Project
You might have an empty target class library called GenerativeWorkflow.Repository. When you generate code using the AnalyserService, the generated code will combine your implementation details into an interface and class per model based on the attributes and implementation details specified. E.g.:
//Auto-generated code
namespace GenerativeWorkflow.Repository
{
public interface ICarRepository
{
public void Add(GenerativeWorkflow.Models.Car entity);
public void Remove(GenerativeWorkflow.Models.Car entity);
}
}
//Auto-generated code
namespace GenerativeWorkflow.Repository
{
public class CarRepository : ICarRepository
{
protected List<GenerativeWorkflow.Models.Car> entities = new();
public void Add(GenerativeWorkflow.Models.Car entity)
{
entities.Add(entity);
}
public void Remove(GenerativeWorkflow.Models.Car entity)
{
entities.Remove(entity);
}
}
}
Configuration
To get started:
- Create your console application
- Add
Generative.Compositionas a dependency to your project - Instantiate the
AnalyserServiceusing aCodeGenerationConfig. E.g.:
var analyserService = new AnalyserService(new Generative.Composition.CodeGenerationConfig
{
SolutionPath = @"D:\Code\GenerativeWorkflow\GenerativeWorkflow\GenerativeWorkflow.sln",
SourceModelProjectName = "GenerativeWorkflow.Models",
SourceImplementationProjectName = "GenerativeWorkflow.SourceRepository",
SourceBaseClassName = "RepositoryBase",
SourceTypeParameterName = "TEntity",
TargetClassSuffix = "Repository",
TargetNamespace = "GenerativeWorkflow.Repository",
TargetInterfaceFolder = @"D:\Code\Generative Workflow\GenerativeWorkflow.Repository\Interfaces",
TargetClassFolder = @"D:\Code\Generative Workflow\GenerativeWorkflow.Repository\DataAccess"
});
Configuration Breakdown
| Property | Description |
|---|---|
SolutionPath |
The absolute path to the solution containing your source code |
SourceModelProjectName |
The name of your model class library |
SourceImplementationProjectName |
The name of the project containing your implementation class library |
SourceBaseClassName |
The name of the base class in your implementation class library |
SourceTypeParameterName |
The name of the type parameter in your implementation class library that will be substituted with your model type during code generation |
TargetClassSuffix |
The name that will be added to the end of each generated class' name in your target library |
TargetNamespace |
The namespace of your generated code in your target library |
TargetInterfaceFolder |
The absolute path of the folder you want generated interfaces to be written to in your target library |
TargetClassFolder |
The absolute path of the folder you want generated classes to be written to in your target library |
Code Generation
With your configuration set up, you can generate code in your console application by calling:
await analyserService.AnalyseSolutionAsync();
Limitations
- Regarding the base class defined in your implementation class library:
- The library will only copy properties to the target classes, nothing else
- The library expects the root of the class to be a namespace. E.g.:
- This will work:
namespace GenerativeWorkflow.SourceRepository { public class RepositoryBase<TEntity> { protected List<TEntity> entities = new(); } } - This will not work:
namespace GenerativeWorkflow.SourceRepository; public class RepositoryBase<TEntity> { protected List<TEntity> entities = new(); }
- This will work:
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net6.0 is compatible. 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. |
-
net6.0
- Microsoft.Build.Framework (>= 17.6.3)
- Microsoft.Build.Locator (>= 1.5.5)
- Microsoft.CodeAnalysis.CSharp (>= 4.6.0)
- Microsoft.CodeAnalysis.CSharp.Workspaces (>= 4.6.0)
- Microsoft.CodeAnalysis.Workspaces.MSBuild (>= 4.6.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.0 | 207 | 3/21/2024 |