AutoEfDto 1.0.3

dotnet add package AutoEfDto --version 1.0.3
NuGet\Install-Package AutoEfDto -Version 1.0.3
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="AutoEfDto" Version="1.0.3" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add AutoEfDto --version 1.0.3
#r "nuget: AutoEfDto, 1.0.3"
#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.
// Install AutoEfDto as a Cake Addin
#addin nuget:?package=AutoEfDto&version=1.0.3

// Install AutoEfDto as a Cake Tool
#tool nuget:?package=AutoEfDto&version=1.0.3

AutoDto

AutoDto is a C# source generator for scaffolding basic data transfer object (DTO) classes from database model classes. When exposing an API to perform CRUD operations it is often desirable to separate the user-facing data structures from those mapped to the underlying schema. For instance, a request to create a new entry might not expose an ID field if it is automatically generated by the database, but such a field will be present in a model scaffolded by an ORM. AutoDto was created to ease the burden of writing lots of boilerplate DTO classes that are often very similar to their corresponding DB models.

AutoDto is aimed at projects utilizing Entity Framework Core, and will only generate DTOs for types referenced in a class deriving from DbContext. This is implemented simply by searching through the root namespace of the assembly where AutoDto is added and searching recursively for the first class derived from DbContext - there is no logic in place to ensure that this is in fact Entity Framework Core, just that the base type is named DbContext. Once a subclass of DbContext is found, AutoDto iterates over each property of the class that is a DbSet, and scaffolds Request/Response DTO classes for the types referenced in the DbSets.

Note that the current implementation is very simple, and will only handle properties in the target classes. It is designed to handle basic object properties as well as ICollections - basically, if you've scaffolded your EF models from an existing database, AutoDto should be fully compatible with your project.

Generated classes support recursion - for instance, if you have a class named Child, and another class Parent that has a property of type ICollection<Child>, then AutoDto would generate the class CreateParentRequest with a property of type ICollection<CreateChildRequest> as long as the Child class is also targeted for scaffolding (see the Configuration section).

Installation

AutoDto is packaged using nuget, hosted at this link.

To install, open a terminal in your project directory and run the following: dotnet add package AutoEfDto --version 1.0.3

Or in the Visual Studio Package Manager Console: NuGet\Install-Package AutoEfDto -Version 1.0.3

Basic Usage

A typical project utilizing EF Core will contain a database context class:

internal class ExampleDbContext : DbContext
{
    public virtual DbSet<ParentClass> ParentClass { get; set; }

    public virtual DbSet<ChildClass> ChildClass { get; set; }
}

As well as model classes corresponding to the database tables:

// ChildClass.cs
internal class ChildClass
{
    public int Id { get; set; }
    public string Name { get; set; }
}

// ParentClass.cs
internal class ParentClass
{
    public int Id { get; set; }
    public virtual ChildClass? FavoriteChild { get; set; } = null!;
    public virtual ICollection<ChildClass> Children { get; set; } = new List<ChildClass>();
}

In its default configuration, AutoDto would generate separate Create, Read, Update, and Delete request DTOs as follows:

// CreateChildClassRequest.cs
public partial class CreateChildClassRequest
{
    public int Id { get; set; }
    public string Name { get; set; }
}

// CreateParentClassRequest.cs
public partial class CreateParentClassRequest
{
    public int Id { get; set; }
    public CreateChildClassRequest? FavoriteChild { get; set; } = null!;
    public ICollection<CreateChildClassRequest> Children { get; set; } = new List<CreateChildClassRequest>();
}

As well as a generic response DTO for each type:

// ChildClassResponse.cs
public partial class ChildClassResponse
{
    public int Id { get; set; }
    public string Name { get; set; }
}

// ParentClassResponse.cs
public partial class ParentClassResponse
{
    public int Id { get; set; }
    public ChildClassResponse? FavoriteChild { get; set; } = null!;
    public ICollection<ChildClassResponse> Children { get; set; } = new List<ChildClassResponse>();
}

By default, request DTOs follow the naming convention "{RequestType}{BaseClassName}Request" where RequestType is one of "Create", "Read", "Update", or "Delete".

All generated classes have the partial modifier so that they can be extended separately within your project without editing the source files, which are overwritten at compile time.

Configuration

There are many reasons for leveraging DTOs as an abstraction, and generally DTOs will not be a one-to-one mapping of the corresponding domain models. AutoDto includes several attributes that can be used to customize its behavior and conventions to better fit different use-cases. The most important is the AutoDtoConfiguration attribute, which can be applied to the DbContext class to set the default behavior.

The AutoDtoConfiguration attribute can also be applied to individual classes to override the default behavior for that individual class.

Configuration Attribute

The default configuration for AutoDto (which applies when no AutoDtoConfiguration attribute is found) is equivalent to the following:

[AutoDtoConfiguration(
    ClassDiscoveryBehavior= ClassDiscoveryBehavior.Default, 
    RequestDtoNamingTemplate = "{RequestType}{BaseClassName}Request",
    ResponseDtoNamingTemplate = "{ResponseType}{BaseClassName}Response",
    GenerateRequestTypes = GeneratedRequestType.Default, 
    GenerateResponseTypes = GeneratedResponseType.Default,
    RequestTypesIncludingAllPropertiesByDefault = GeneratedRequestType.All,
    ResponseTypesIncludingAllPropertiesByDefault = GeneratedResponseType.All)]
Class Discovery Behavior

The ClassDiscoveryBehavior parameter configures which classes AutoDto will generate DTOs for by default. It is defined as follows:

public enum ClassDiscoveryBehavior
{
    IncludeAllDbSets,
    ExcludeAll,
    Default = IncludeAllDbSets,
}

IncludeAllDbSets is the default value, instructing AutoDto to generate DTOs for all types for which there is a DbSet within the DbContext, except those marked with an AutoDtoIgnore attribute. ExcludeAll will cause AutoDto to only generate DTOs for classes marked with an AutoDtoInclude attribute. Note AutoDto will still only discover classes for which there is a DbSet.

Request Naming Convention

The RequestDtoNamingTemplate parameter allows you to customize the names of the generated request DTOs. It accepts a string value that can optionally contain the substrings {RequestType} and {BaseClassName}. If present, AutoDto will replace {RequestType} with "Create", "Read", "Update", or "Delete" for each respective DTO class, while {BaseClassName} will be replaced with the original class name for all of the request types. Any other characters in the string will be used exactly as they appear in the generated class names.

The default template is "{RequestType}{BaseClassName}Request".

IMPORTANT: if multiple request types are being generated (see Generated Request Types), you must include {RequestType} in the naming template to guarantee the generated classes will have unique names. Failure to do so may lead to invalid code generation.

Response Naming Convention

The ResponseDtoNamingTemplate parameter allows you to customize the names of the generated response DTOs. It accepts a string value that can optionally contain the substrings {ResponseType} and {BaseClassName}. If present, AutoDto will replace {ResponseType} with "Create", "Read", "Update", or "Delete" for each respective DTO class, while {BaseClassName} will be replaced with the original class name for all of the response types. Any other characters in the string will be used exactly as they appear in the generated class names. Note that for the "Generic" response type, {ResponseType} will be replaced with an empty string.

The default template is "{ResponseType}{BaseClassName}Response".

IMPORTANT: if multiple response types are being generated (see Generated Response Types), you must include {ResponseType} in the naming template to guarantee the generated classes will have unique names. Failure to do so may lead to invalid code generation.

Generated Request Types

The GenerateRequestTypes parameter specifies which types of request DTOs AutoDto will generate. It is defined as the following:

[Flags]
public enum GeneratedRequestType
{
    None = 0,
    Create = 1,
    Read = 2,
    Update = 4,
    Delete = 8,
    All = Create | Read | Update | Delete,
    Default = Create | Update,
}

You can explicitly specify which request types you want to be generated by using bitwise-or, for instance GenerateRequestTypes = GeneratedRequestType.Create | GeneratedRequestType.Update will only generate Create and Update request types.

Generated Response Types

The GeneratedResponseType parameter specifies which types of response DTOs AutoDto will generate. It is defined as the following:

[Flags]
public enum GeneratedResponseType
{
    None = 0,
    Create = 1,
    Read = 2,
    Update = 4,
    Delete = 8,
    AllExceptGeneric = Create | Read | Update | Delete,
    All = Create | Read | Update | Delete | Generic,
    Generic = 16,
    Default = Generic,
}

You can explicitly specify which response types you want to be generated by using bitwise-or, for instance GeneratedResponseTypes = GeneratedResponseType.Create | GeneratedResponseType.Update will only generate Create and Update response types.

Properties Included in Requests

The RequestTypesIncludingAllPropertiesByDefault parameter can be used to indicate that only some generated request types should default to including all of the properties present in the base class. For example, passing RequestTypesIncludingAllPropertiesByDefault = GeneratedRequestType.Create | GeneratedRequestType.Update will cause AutoDto to include all of the properties present in the base class when generating the Create and Update request types, except for properties with an AutoDtoIgnore attribute. For all other request types, AutoDto will only include properties with an AutoDtoInclude attribute.

Properties Included in Responses

The ResponseTypesIncludingAllPropertiesByDefault parameter can be used to indicate that only some generated response types should default to including all of the properties present in the base class. For example, passing ResponseTypesIncludingAllPropertiesByDefault = GeneratedResponseType.Create | GeneratedResponseType.Update will cause AutoDto to include all of the properties present in the base class when generating the Create and Update response types, except for properties with an AutoDtoIgnore attribute. For all other response types, AutoDto will only include properties with an AutoDtoInclude attribute.

Ignore Attribute

The [AutoDtoIgnore] attribute can be used to indicate that a class or a property should be ignored by AutoDto.

When present on a class, DTOs will not be generated for that class regardless of other configuration parameters.

When present on a property, that property will not be included in any request DTOs specified by the RequestTypesWherePropertyIsIgnored parameter nor any response DTOs specified by the ResponseTypesWherePropertyIsIgnored parameter. The [AutoDtoIgnore] attribute without any parameters is equivalent to the following:

[AutoDtoIgnore(
    RequestTypesWherePropertyIsIgnored = GeneratedRequestType.All,
    ResponseTypesWherePropertyIsIgnored = GeneratedResponseType.All)]

Thus by default for a property, the [AutoDtoIgnore] attribute will cause AutoDto to exclude the property from all generated DTOs.

Include Attribute

The [AutoDtoInclude] attribute can be used to indicate that a class or a property should be included by AutoDto.

When present on a class, DTOs will be generated for that class regardless of other configuration parameters.

When present on a property, that property will only be included in request DTOs specified by the RequestTypesWherePropertyIsIncluded parameter as well as response DTOs specified by the ResponseTypesWherePropertyIsIncluded parameter, unless AutoDto is configured to include all properties by default. This attribute is meant to be used when AutoDto is configured globally or for the class containing the property not to include all properties (see Properties Included in Requests and Properties Included in Responses) The [AutoDtoInclude] attribute without any parameters is equivalent to the following:

[AutoDtoInclude(
    RequestTypesWherePropertyIsIncluded = GeneratedRequestType.All,
    ResponseTypesWherePropertyIsIncluded = GeneratedResponseType.All)]

Thus by default for a property, the [AutoDtoInclude] attribute will cause AutoDto to include the property in all generated DTOs.

Contributing

Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.

License

MIT

Product 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. 
.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.

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.3 178 7/12/2023