RoyalCode.SmartSelector 0.4.0

dotnet add package RoyalCode.SmartSelector --version 0.4.0
                    
NuGet\Install-Package RoyalCode.SmartSelector -Version 0.4.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="RoyalCode.SmartSelector" Version="0.4.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="RoyalCode.SmartSelector" Version="0.4.0" />
                    
Directory.Packages.props
<PackageReference Include="RoyalCode.SmartSelector" />
                    
Project file
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 RoyalCode.SmartSelector --version 0.4.0
                    
#r "nuget: RoyalCode.SmartSelector, 0.4.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 RoyalCode.SmartSelector@0.4.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=RoyalCode.SmartSelector&version=0.4.0
                    
Install as a Cake Addin
#tool nuget:?package=RoyalCode.SmartSelector&version=0.4.0
                    
Install as a Cake Tool

SmartSelector

Gerador/Source Generator para criar automaticamente projeções (Expression<Func<TFrom, TDto>>), métodos auxiliares e propriedades em DTOs, reduzindo drasticamente boilerplate em consultas LINQ / EF Core.

Principais Recursos

  • [AutoSelect<TFrom>]: gera expressão de seleção, método From, extensões Select{Dto} / To{Dto}.
  • [AutoProperties] ou [AutoProperties<TFrom>]: gera propriedades simples automaticamente (primitivos, string, bool, DateTime, enum, struct, coleções simples IEnumerable<T> desses tipos).
  • Flattening por convenção: nomes concatenados em PascalCase resolvem cadeias aninhadas (ex.: CustomerAddressCountryRegionName ? a.Customer.Address.Country.Region.Name).
  • Exclusão de propriedades: Exclude = [ nameof(Entity.Prop) ].
  • Diagnósticos de compilação para uso incorreto, tipos incompatíveis e conflitos.

Quickstart

  1. Instalação
<ItemGroup>
  <PackageReference Include="RoyalCode.SmartSelector" Version="x.y.z" />
  <PackageReference Include="RoyalCode.SmartSelector.Generators" Version="x.y.z" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
</ItemGroup>
  1. Anote seu DTO
[AutoSelect<User>, AutoProperties]
public partial class UserDetails { }
  1. Consulte com EF Core
var list = db.Users.SelectUserDetails().ToList();
var dto  = UserDetails.From(user);
var expr = UserDetails.SelectUserExpression; // reutilizável / componível

Escopo e foco

  • Sem custom resolvers, conditional mapping ou naming policies.
  • Foco: projeções traduzíveis por EF Core e mapeamento 1x1 (estilo Adapt do Mapster).

Links úteis

  • Documentação completa: src/docs.md
  • Projeto Demo: RoyalCode.SmartSelector.Demo
  • Benchmarks: RoyalCode.SmartSelector.Benchmarks

Frameworks e pacotes suportados

  • Runtime lib: RoyalCode.SmartSelector (TFMs: .NET 8, .NET 9, .NET 10)
  • Generator: RoyalCode.SmartSelector.Generators (TFM: .NET Standard 2.0, instalado como Analyzer)

Exemplo 1 – Projeção Simples

[AutoSelect<User>, AutoProperties]
public partial class UserDetails { }

// Uso
var list = db.Users.SelectUserDetails().ToList();
var dto  = UserDetails.From(user);
var expr = UserDetails.SelectUserExpression; // reutilizável / componível

Código gerado (essencial):

public static Expression<Func<User, UserDetails>> SelectUserExpression => u => new UserDetails
{ 
    Id = u.Id, 
    Name = u.Name
};

public static UserDetails From(User u) => (selectUserFunc ??= SelectUserExpression.Compile())(u);

Exemplo 2 – Objeto Aninhado + Exclusão

[AutoSelect<Book>, AutoProperties(Exclude = [ nameof(Book.Sku) ])]
public partial class BookDetails
{
    public ShelfDetails Shelf { get; set; }
}

[AutoProperties<Shelf>]
public partial class ShelfDetails { }

Trecho gerado:

new BookDetails
{
    Shelf = new ShelfDetails
    {
        Id = a.Shelf.Id,
        Location = a.Shelf.Location
    },
    Price = a.Price,
};
// Sku excluído

Exemplo 3 – Flattening Profundo

public class Order 
{ 
    public Customer Customer { get; set; }
}

// Customer -> Address -> Country -> Region
[AutoSelect<Order>]
public partial class OrderDetails
{
    public string CustomerAddressCountryRegionName { get; set; }
}

Trecho da expressão:

CustomerAddressCountryRegionName = a.Customer.Address.Country.Region.Name

Exemplos mínimos por atributo

  • AutoSelect<T>:
[AutoSelect<Product>]
public partial class ProductDetails { }

// Uso:
db.Products.SelectProductDetails().ToList();
  • AutoProperties:
[AutoSelect<Simple>, AutoProperties]
public partial class SimpleDto { /* propriedades simples geradas automaticamente */ }

Para usar AutoProperties, o tipo de origem é inferido do AutoSelect<TFrom>.

  • AutoProperties<TFrom>:
[AutoProperties<User>]
public partial class UserSnapshot { }
  • DTO aninhado + Exclude:
[AutoSelect<Order>, AutoProperties<Order>(Exclude = [ nameof(Order.InternalCode) ])]
public partial class OrderDetails 
{
    public CustomerDetails Customer { get; set; }
}

[AutoProperties<Customer>]
public partial class CustomerDetails { }
  • Flattening por nome:
[AutoSelect<Order>]
public partial class OrderFlat 
{ 
    public string CustomerAddressCity { get; set; }
}

// Gera: CustomerAddressCity = a.Customer.Address.City

Regras de Flattening

  • Nome da propriedade = concatenação PascalCase dos segmentos do caminho.
  • Sem necessidade de atributos extras.

Tipos Suportados em AutoProperties

  • Primitivos numéricos, bool, string, char, DateTime / nullable simples
  • enum, struct
  • IEnumerable<T> onde T é suportado acima / enum / struct

Exclusões

[AutoProperties<Product>(Exclude = [ nameof(Product.InternalCode), nameof(Product.Secret) ])]

Diagnósticos Principais

  • Tipos inválidos ou classe não partial (RCSS000).
  • Propriedade não encontrada (RCSS001).
  • Tipos incompatíveis (RCSS002).
  • Uso incorreto de atributos (RCSS003RCSS005).

Limitações Resumidas

  • Sem renome/alias explícito ainda (MapFrom).
  • Sem transformações de tipo (formatters / custom converters).
  • Desambiguação de flattening limitada em colisões de prefixo.

Boas Práticas

  • Use nameof em Exclude.
  • Prefira consumir a expressão gerada para reutilização e composição LINQ.
  • Para caminhos muito longos, avalie DTOs aninhados por clareza.

FAQ Rápido

Pergunta Resposta
Preciso configurar algo no runtime? Não, pura geração de código.
Funciona com EF Core? Sim, a expressão é traduzível.
Posso só gerar propriedades? Sim: [AutoProperties<TFrom>].
Flattening precisa de atributo? Não, é por nome.

Mais Informações

  • Documentação detalhada: ver docs.md no repositório.
  • Projeto Demo: ver RoyalCode.SmartSelector.Demo.
  • Benchmarks: ver RoyalCode.SmartSelector.Benchmarks.

Happy coding!

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  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 is compatible.  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 is compatible.  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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net10.0

    • No dependencies.
  • net8.0

    • No dependencies.
  • net9.0

    • No dependencies.

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
0.4.0 94 1/16/2026
0.3.0 182 10/20/2025
0.2.0 180 10/9/2025
0.1.0 162 5/23/2025