Overview
Bias against bespoke internal implementations by preferring mature open-source tools and
composable libraries. When custom code is unavoidable, enforce justification rubrics that
require explicit rationale, ownership, versioning, testing, and security considerations.
When to Use
- Proposals to write internal mappers, code generators, custom build scripts, or DI containers
- Reviews where new internal tooling or bespoke framework layers are introduced
- Evaluating whether to build vs buy/adopt for any infrastructure component
- Reviewing PRs that add custom implementations for common concerns (validation, retries, caching)
- Architectural decisions involving custom scaffolding or automation scripts
Core Workflow
- Identify the concern: Determine what functionality is being proposed (mapping, validation, CLI, etc.)
- Search for OSS alternatives: Evaluate mature open-source libraries that solve the same problem
- Compare trade-offs: Assess maintenance burden, test effort, performance, and community support
- Apply decision framework: Choose OSS unless clear justification exists for bespoke code
- Require justification rubric: If bespoke code is proposed, demand explicit rationale,
ownership, versioning, tests, and security considerations
- Document decision: Record OSS evaluation, selection rationale, and maintenance plan
- Verify in PR: Check that PR includes evidence of OSS evaluation and rubric satisfaction
Core
Defaults
- Prefer OSS libraries/tools over bespoke implementations for:
- mapping,
- validation,
- retries/circuit breakers,
- caching,
- scheduling,
- logging/metrics,
- CLI/automation tools,
- test harnesses.
Principles
- "Library before framework": small, composable components are preferred.
- "Configuration before code" when it improves transparency and reduces maintenance.
- "Script last": if unavoidable, scripts must be versioned, tested, and documented.
Load: checklists
Bespoke justification rubric (required)
A bespoke internal tool/framework must include:
- explicit rationale why OSS alternatives are insufficient,
- ownership (team/person) and support model,
- versioning and deprecation policy,
- tests and documentation,
- security and supply-chain considerations.
Load: examples
- Prefer an OSS formatter/analyzer/CLI over a custom PowerShell script.
- Prefer an OSS mapping generator over internal reflection-based mapping.
Load: enforcement
- Reject PRs introducing new internal framework layers without:
- justification rubric satisfied,
- a documented maintenance plan,
- confirmation that OSS options were evaluated and licensing revalidated.
Load: PR review checklist
When reviewing PRs proposing new custom code, verify:
Decision rule: If OSS evaluation is incomplete or rubric unsatisfied, request
changes before approving.
Load: worked example
Scenario: Object Mapping in .NET
Requirement: Convert DTOs to domain entities in a health insurance claims
system.
Option A: Custom Reflection-Based Mapper (Bespoke)
public class ClaimMapper
{
public DomainClaim MapToClaim(ClaimDto dto)
{
var claim = new DomainClaim();
// Manual property assignment for ~30 properties
claim.ClaimId = dto.Id;
claim.MemberId = dto.MemberId;
// ... 28 more assignments
return claim;
}
}
Costs:
- Maintenance: Manual updates required when entities change (tight coupling)
- Testing: Every mapping path must be tested manually
- Performance: Reflection-based or slow property copying
- Versioning: No clear deprecation path if mapping rules change
- Ownership: Who maintains this when the original author leaves?
OSS Evaluation: Rejected without justification.
Option B: AutoMapper (OSS Library)
services.AddAutoMapper(cfg =>
{
cfg.CreateMap<ClaimDto, DomainClaim>();
});
Strengths:
- Maintenance: Configuration-driven, auto-discovers properties by name/convention
- Testing: Industry-standard test patterns, extensive test suite in OSS
- Performance: Mature optimization, benchmarked at scale
- Versioning: Library follows SemVer; breaking changes documented
- Ownership: Active maintainers, funding model established
- Documentation: Comprehensive guides for complex mappings
Risks: Dependency on external library (mitigated by extensive industry
adoption and source availability).
Option C: Mapperly (Modern OSS Library)
[Mapper]
public partial class ClaimMapper
{
public partial DomainClaim MapToClaim(ClaimDto dto);
}
Strengths:
- Zero runtime overhead via source generation (better than AutoMapper for
performance-critical paths)
- Explicit, generated code is auditable
- Compile-time safety
- Minimal dependencies
- Fastest execution path
Trade-off: Newer library (active development but smaller ecosystem than
AutoMapper).
Decision Framework
| Criterion |
Bespoke |
AutoMapper |
Mapperly |
| Maintenance burden |
High (manual) |
Low (config) |
Low (generated) |
| Test effort |
High |
Medium |
Low |
| Performance |
Unknown |
Good |
Excellent |
| Versioning clarity |
None |
Documented |
Documented |
| Ownership model |
Implicit |
Explicit |
Explicit |
| Industry adoption |
N/A |
Mature (15+ years) |
Growing (active) |
| Time to value |
Slow (30+ lines) |
Fast (2 lines) |
Fast (1 line) |
Recommendation
Use Mapperly for new systems (source generation, zero deps, best
performance) or AutoMapper for teams with existing expertise.
Reject bespoke mapper unless:
- Performance benchmarks prove custom code materially faster (at scale)
- Mapping logic is genuinely bespoke (not property-to-property)
- Ownership, versioning, and testing documented per rubric
Verification
Evidence required in PR:
Red Flags - STOP
These statements indicate bypass of bespoke minimisation principles:
| Thought |
Reality |
| "We need full control over this" |
OSS libraries offer customisation; evaluate before rejecting |
| "OSS is too heavy for our needs" |
Measure actual overhead; most libraries are well-optimised |
| "We're special, our case is unique" |
Most "unique" cases have OSS solutions; search thoroughly |
| "I can write this in a day" |
Maintenance cost exceeds initial development; OSS shifts burden |
| "External dependencies are risky" |
Well-maintained OSS with active communities reduces risk |
| "We'll document it later" |
Undocumented internal code becomes unmaintainable quickly |
Converted and distributed by TomeVault — claim your Tome and manage your conversions.
1---2name: dotnet-bespoke-code-minimisation3description: Bias against bespoke scripts/frameworks by default; prefer mature open-source tools and composable libraries with clear ownership. Use when this capability is needed.4---56## Overview78Bias against bespoke internal implementations by preferring mature open-source tools and9composable libraries. When custom code is unavoidable, enforce justification rubrics that10require explicit rationale, ownership, versioning, testing, and security considerations.1112## When to Use1314- Proposals to write internal mappers, code generators, custom build scripts, or DI containers15- Reviews where new internal tooling or bespoke framework layers are introduced16- Evaluating whether to build vs buy/adopt for any infrastructure component17- Reviewing PRs that add custom implementations for common concerns (validation, retries, caching)18- Architectural decisions involving custom scaffolding or automation scripts1920## Core Workflow21221. **Identify the concern**: Determine what functionality is being proposed (mapping, validation, CLI, etc.)232. **Search for OSS alternatives**: Evaluate mature open-source libraries that solve the same problem243. **Compare trade-offs**: Assess maintenance burden, test effort, performance, and community support254. **Apply decision framework**: Choose OSS unless clear justification exists for bespoke code265. **Require justification rubric**: If bespoke code is proposed, demand explicit rationale,27 ownership, versioning, tests, and security considerations286. **Document decision**: Record OSS evaluation, selection rationale, and maintenance plan297. **Verify in PR**: Check that PR includes evidence of OSS evaluation and rubric satisfaction3031## Core3233### Defaults3435- Prefer OSS libraries/tools over bespoke implementations for:36 - mapping,37 - validation,38 - retries/circuit breakers,39 - caching,40 - scheduling,41 - logging/metrics,42 - CLI/automation tools,43 - test harnesses.4445### Principles4647- "Library before framework": small, composable components are preferred.48- "Configuration before code" when it improves transparency and reduces maintenance.49- "Script last": if unavoidable, scripts must be versioned, tested, and documented.5051## Load: checklists5253### Bespoke justification rubric (required)5455A bespoke internal tool/framework must include:5657- explicit rationale why OSS alternatives are insufficient,58- ownership (team/person) and support model,59- versioning and deprecation policy,60- tests and documentation,61- security and supply-chain considerations.6263## Load: examples6465- Prefer an OSS formatter/analyzer/CLI over a custom PowerShell script.66- Prefer an OSS mapping generator over internal reflection-based mapping.6768## Load: enforcement6970- Reject PRs introducing new internal framework layers without:71 - justification rubric satisfied,72 - a documented maintenance plan,73 - confirmation that OSS options were evaluated and licensing revalidated.7475## Load: PR review checklist7677When reviewing PRs proposing new custom code, verify:7879- [ ] **OSS Evaluation**: Has the author evaluated mature OSS alternatives?80 (Expect evidence: library list, why each was rejected)81- [ ] **Justification Rubric**: If OSS rejected, is the full rubric satisfied?82 - [ ] Explicit rationale for OSS insufficiency83 - [ ] Named owner (team/person) responsible for maintenance84 - [ ] Versioning and deprecation policy defined85 - [ ] Tests covering critical functionality86 - [ ] Security and supply-chain considerations documented87- [ ] **Library vs Framework**: For applicable cases, has the author chosen88 libraries over frameworks?89- [ ] **Documentation**: Is maintenance burden and support model clearly90 communicated?91- [ ] **Red Flags**: Watch for rationalizations that bypass evaluation (e.g.,92 "we need full control", "OSS is too heavy", "we're special")9394**Decision rule**: If OSS evaluation is incomplete or rubric unsatisfied, request95changes before approving.9697## Load: worked example9899### Scenario: Object Mapping in .NET100101**Requirement**: Convert DTOs to domain entities in a health insurance claims102system.103104#### Option A: Custom Reflection-Based Mapper (Bespoke)105106```csharp107public class ClaimMapper108{109 public DomainClaim MapToClaim(ClaimDto dto)110 {111 var claim = new DomainClaim();112 // Manual property assignment for ~30 properties113 claim.ClaimId = dto.Id;114 claim.MemberId = dto.MemberId;115 // ... 28 more assignments116 return claim;117 }118}119```120121**Costs**:122123- Maintenance: Manual updates required when entities change (tight coupling)124- Testing: Every mapping path must be tested manually125- Performance: Reflection-based or slow property copying126- Versioning: No clear deprecation path if mapping rules change127- Ownership: Who maintains this when the original author leaves?128129**OSS Evaluation**: Rejected without justification.130131#### Option B: AutoMapper (OSS Library)132133```csharp134services.AddAutoMapper(cfg =>135{136 cfg.CreateMap<ClaimDto, DomainClaim>();137});138```139140**Strengths**:141142- Maintenance: Configuration-driven, auto-discovers properties by name/convention143- Testing: Industry-standard test patterns, extensive test suite in OSS144- Performance: Mature optimization, benchmarked at scale145- Versioning: Library follows SemVer; breaking changes documented146- Ownership: Active maintainers, funding model established147- Documentation: Comprehensive guides for complex mappings148149**Risks**: Dependency on external library (mitigated by extensive industry150adoption and source availability).151152#### Option C: Mapperly (Modern OSS Library)153154```csharp155[Mapper]156public partial class ClaimMapper157{158 public partial DomainClaim MapToClaim(ClaimDto dto);159}160```161162**Strengths**:163164- Zero runtime overhead via source generation (better than AutoMapper for165 performance-critical paths)166- Explicit, generated code is auditable167- Compile-time safety168- Minimal dependencies169- Fastest execution path170171**Trade-off**: Newer library (active development but smaller ecosystem than172AutoMapper).173174#### Decision Framework175176| Criterion | Bespoke | AutoMapper | Mapperly |177| ------------------ | ---------------- | ------------------ | ---------------- |178| Maintenance burden | High (manual) | Low (config) | Low (generated) |179| Test effort | High | Medium | Low |180| Performance | Unknown | Good | Excellent |181| Versioning clarity | None | Documented | Documented |182| Ownership model | Implicit | Explicit | Explicit |183| Industry adoption | N/A | Mature (15+ years) | Growing (active) |184| Time to value | Slow (30+ lines) | Fast (2 lines) | Fast (1 line) |185186#### Recommendation187188**Use Mapperly** for new systems (source generation, zero deps, best189performance) or **AutoMapper** for teams with existing expertise.190191**Reject bespoke mapper** unless:192193- Performance benchmarks prove custom code materially faster (at scale)194- Mapping logic is genuinely bespoke (not property-to-property)195- Ownership, versioning, and testing documented per rubric196197#### Verification198199Evidence required in PR:200201- [ ] OSS libraries evaluated: AutoMapper, Mapperly, TinyMapper considered202- [ ] Selection rationale: "Mapperly chosen for source-gen performance and203 zero-dependency model"204- [ ] Tests: Core mappings covered205- [ ] Documentation: Mapping conventions explained (if non-obvious)206207## Red Flags - STOP208209These statements indicate bypass of bespoke minimisation principles:210211| Thought | Reality |212| ----------------------------------- | --------------------------------------------------------------- |213| "We need full control over this" | OSS libraries offer customisation; evaluate before rejecting |214| "OSS is too heavy for our needs" | Measure actual overhead; most libraries are well-optimised |215| "We're special, our case is unique" | Most "unique" cases have OSS solutions; search thoroughly |216| "I can write this in a day" | Maintenance cost exceeds initial development; OSS shifts burden |217| "External dependencies are risky" | Well-maintained OSS with active communities reduces risk |218| "We'll document it later" | Undocumented internal code becomes unmaintainable quickly |219220---221> Converted and distributed by [TomeVault](https://tomevault.io/claim/mcj-coder) — claim your Tome and manage your conversions.222<!-- tomevault:4.0:skill_md:2026-04-14 -->