\documentclass[10pt,a4paper]{article} % Packages \usepackage{fancyhdr} % For header and footer \usepackage{multicol} % Allows multicols in tables \usepackage{tabularx} % Intelligent column widths \usepackage{tabulary} % Used in header and footer \usepackage{hhline} % Border under tables \usepackage{graphicx} % For images \usepackage{xcolor} % For hex colours %\usepackage[utf8x]{inputenc} % For unicode character support \usepackage[T1]{fontenc} % Without this we get weird character replacements \usepackage{colortbl} % For coloured tables \usepackage{setspace} % For line height \usepackage{lastpage} % Needed for total page number \usepackage{seqsplit} % Splits long words. %\usepackage{opensans} % Can't make this work so far. Shame. Would be lovely. \usepackage[normalem]{ulem} % For underlining links % Most of the following are not required for the majority % of cheat sheets but are needed for some symbol support. \usepackage{amsmath} % Symbols \usepackage{MnSymbol} % Symbols \usepackage{wasysym} % Symbols %\usepackage[english,german,french,spanish,italian]{babel} % Languages % Document Info \author{vikbert (vikbert)} \pdfinfo{ /Title (onion-architecture-symfony.pdf) /Creator (Cheatography) /Author (vikbert (vikbert)) /Subject (Onion Architecture + Symfony Cheat Sheet) } % Lengths and widths \addtolength{\textwidth}{6cm} \addtolength{\textheight}{-1cm} \addtolength{\hoffset}{-3cm} \addtolength{\voffset}{-2cm} \setlength{\tabcolsep}{0.2cm} % Space between columns \setlength{\headsep}{-12pt} % Reduce space between header and content \setlength{\headheight}{85pt} % If less, LaTeX automatically increases it \renewcommand{\footrulewidth}{0pt} % Remove footer line \renewcommand{\headrulewidth}{0pt} % Remove header line \renewcommand{\seqinsert}{\ifmmode\allowbreak\else\-\fi} % Hyphens in seqsplit % This two commands together give roughly % the right line height in the tables \renewcommand{\arraystretch}{1.3} \onehalfspacing % Commands \newcommand{\SetRowColor}[1]{\noalign{\gdef\RowColorName{#1}}\rowcolor{\RowColorName}} % Shortcut for row colour \newcommand{\mymulticolumn}[3]{\multicolumn{#1}{>{\columncolor{\RowColorName}}#2}{#3}} % For coloured multi-cols \newcolumntype{x}[1]{>{\raggedright}p{#1}} % New column types for ragged-right paragraph columns \newcommand{\tn}{\tabularnewline} % Required as custom column type in use % Font and Colours \definecolor{HeadBackground}{HTML}{333333} \definecolor{FootBackground}{HTML}{666666} \definecolor{TextColor}{HTML}{333333} \definecolor{DarkBackground}{HTML}{78B50E} \definecolor{LightBackground}{HTML}{F6FAEF} \renewcommand{\familydefault}{\sfdefault} \color{TextColor} % Header and Footer \pagestyle{fancy} \fancyhead{} % Set header to blank \fancyfoot{} % Set footer to blank \fancyhead[L]{ \noindent \begin{multicols}{3} \begin{tabulary}{5.8cm}{C} \SetRowColor{DarkBackground} \vspace{-7pt} {\parbox{\dimexpr\textwidth-2\fboxsep\relax}{\noindent \hspace*{-6pt}\includegraphics[width=5.8cm]{/web/www.cheatography.com/public/images/cheatography_logo.pdf}} } \end{tabulary} \columnbreak \begin{tabulary}{11cm}{L} \vspace{-2pt}\large{\bf{\textcolor{DarkBackground}{\textrm{Onion Architecture + Symfony Cheat Sheet}}}} \\ \normalsize{by \textcolor{DarkBackground}{vikbert (vikbert)} via \textcolor{DarkBackground}{\uline{cheatography.com/20854/cs/23882/}}} \end{tabulary} \end{multicols}} \fancyfoot[L]{ \footnotesize \noindent \begin{multicols}{3} \begin{tabulary}{5.8cm}{LL} \SetRowColor{FootBackground} \mymulticolumn{2}{p{5.377cm}}{\bf\textcolor{white}{Cheatographer}} \\ \vspace{-2pt}vikbert (vikbert) \\ \uline{cheatography.com/vikbert} \\ \end{tabulary} \vfill \columnbreak \begin{tabulary}{5.8cm}{L} \SetRowColor{FootBackground} \mymulticolumn{1}{p{5.377cm}}{\bf\textcolor{white}{Cheat Sheet}} \\ \vspace{-2pt}Published 31st July, 2020.\\ Updated 13th June, 2021.\\ Page {\thepage} of \pageref{LastPage}. \end{tabulary} \vfill \columnbreak \begin{tabulary}{5.8cm}{L} \SetRowColor{FootBackground} \mymulticolumn{1}{p{5.377cm}}{\bf\textcolor{white}{Sponsor}} \\ \SetRowColor{white} \vspace{-5pt} %\includegraphics[width=48px,height=48px]{dave.jpeg} Measure your website readability!\\ www.readability-score.com \end{tabulary} \end{multicols}} \begin{document} \raggedright \raggedcolumns % Set font size to small. Switch to any value % from this page to resize cheat sheet text: % www.emerson.emory.edu/services/latex/latex_169.html \footnotesize % Small font. \begin{multicols*}{3} \begin{tabularx}{5.377cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{5.377cm}}{\bf\textcolor{white}{Onion Architecture}} \tn % Row 0 \SetRowColor{LightBackground} \mymulticolumn{1}{x{5.377cm}}{Layer: Application Core (application + domain)} \tn % Row Count 1 (+ 1) % Row 1 \SetRowColor{white} \mymulticolumn{1}{x{5.377cm}}{Layer: Presentation} \tn % Row Count 2 (+ 1) % Row 2 \SetRowColor{LightBackground} \mymulticolumn{1}{x{5.377cm}}{Layer: Infrastructure} \tn % Row Count 3 (+ 1) % Row 3 \SetRowColor{white} \mymulticolumn{1}{x{5.377cm}}{Layer: Tests} \tn % Row Count 4 (+ 1) \hhline{>{\arrayrulecolor{DarkBackground}}-} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{5.377cm}{x{1.09494 cm} x{3.88206 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{5.377cm}}{\bf\textcolor{white}{1. Application Core}} \tn % Row 0 \SetRowColor{LightBackground} Domain & has no interaction direct with outerlayer. It represents the domain business and domain logic. It defines always the domain specific entities, value objects, events, exceptions, services, factories, interfaces. \tn % Row Count 7 (+ 7) % Row 1 \SetRowColor{white} \seqsplit{Application} & Application layer manages the internal domain logic. It provides different application services, which enable the communication with presentation, tests and infrastructure. \tn % Row Count 13 (+ 6) \hhline{>{\arrayrulecolor{DarkBackground}}--} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{5.377cm}{x{1.64241 cm} x{3.33459 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{5.377cm}}{\bf\textcolor{white}{1.1 Domain Layer}} \tn % Row 0 \SetRowColor{LightBackground} models & consist of entities, value objects, aggregates \tn % Row Count 2 (+ 2) % Row 1 \SetRowColor{white} repository interface & interfaces to access the business models, which are used by application and implemented by outer layer. For example: infrastructure \tn % Row Count 8 (+ 6) % Row 2 \SetRowColor{LightBackground} assertions & the business rules to adjust changes on business behavior and business models \tn % Row Count 11 (+ 3) % Row 3 \SetRowColor{white} services & domain services define the complex internal communication among the domain models. For example: apply some changes cross different domain models. \tn % Row Count 17 (+ 6) % Row 4 \SetRowColor{LightBackground} events & which can be used to track the state changes of domain \tn % Row Count 20 (+ 3) \hhline{>{\arrayrulecolor{DarkBackground}}--} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{5.377cm}{x{1.89126 cm} x{3.08574 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{5.377cm}}{\bf\textcolor{white}{1.2 Application Layer}} \tn % Row 0 \SetRowColor{LightBackground} events / Event Subcriber & defines the events, which represent the state changes in business domain. for example: \tn % Row Count 4 (+ 4) % Row 1 \SetRowColor{white} services & theser services enable the interaction with internal domains by using the predefined interfaces in the domain layer. \tn % Row Count 9 (+ 5) % Row 2 \SetRowColor{LightBackground} query interface & These interfaces are defined for fetching the domain data. They are commonly used by presentation layer and implemented by infrastructure layer. \tn % Row Count 15 (+ 6) % Row 3 \SetRowColor{white} command & they are simple objects, which are used to change the state of business domain. For example: confirmPayment \tn % Row Count 20 (+ 5) \hhline{>{\arrayrulecolor{DarkBackground}}--} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{5.377cm}{x{1.09494 cm} x{3.88206 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{5.377cm}}{\bf\textcolor{white}{2. Presentation Layer}} \tn % Row 0 \SetRowColor{LightBackground} \seqsplit{controllers} & controllers are the typical gateways for interaction comming from end user. It can be a controller, that represents REST endpoint; or a controller, that renders the web page. \tn % Row Count 6 (+ 6) % Row 1 \SetRowColor{white} \seqsplit{consoles} & It enables the user to access and update the application core via console in terminal. \tn % Row Count 9 (+ 3) % Row 2 \SetRowColor{LightBackground} \seqsplit{templates} & provide the template to define how to represent the business data. for example: template of email, template of exports, template of preview \tn % Row Count 14 (+ 5) % Row 3 \SetRowColor{white} \seqsplit{views/forms} & provide the UX interface to end users \tn % Row Count 16 (+ 2) % Row 4 \SetRowColor{LightBackground} DTO & Data Transfer Object, defines the view model of request and response \tn % Row Count 19 (+ 3) \hhline{>{\arrayrulecolor{DarkBackground}}--} \SetRowColor{LightBackground} \mymulticolumn{2}{x{5.377cm}}{Presentation layer provides the interfaces how end user can drive the business logic} \tn \hhline{>{\arrayrulecolor{DarkBackground}}--} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{5.377cm}{x{1.39356 cm} x{3.58344 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{5.377cm}}{\bf\textcolor{white}{3. Infrastructure layer}} \tn % Row 0 \SetRowColor{LightBackground} doctrine & query implementations \tn % Row Count 1 (+ 1) % Row 1 \SetRowColor{white} mail & repository implementations \tn % Row Count 2 (+ 1) % Row 2 \SetRowColor{LightBackground} filesystem & exports \tn % Row Count 3 (+ 1) % Row 3 \SetRowColor{white} Queue & cron-jobs \tn % Row Count 4 (+ 1) % Row 4 \SetRowColor{LightBackground} SSO & logging \tn % Row Count 5 (+ 1) \hhline{>{\arrayrulecolor{DarkBackground}}--} \SetRowColor{LightBackground} \mymulticolumn{2}{x{5.377cm}}{The {\bf{infrastructure layer}} holds the most low level code. Anything in here should be easy to replace. Code here should never effect anything related to logic, or how your application behaves.} \tn \hhline{>{\arrayrulecolor{DarkBackground}}--} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{5.377cm}{x{1.09494 cm} x{3.88206 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{5.377cm}}{\bf\textcolor{white}{4. Tests Layer}} \tn % Row 0 \SetRowColor{LightBackground} unit tests & test if internal application core works well \tn % Row Count 2 (+ 2) % Row 1 \SetRowColor{white} \seqsplit{integration} & test if the communication between application core and external services in infrastructure layer is possible \tn % Row Count 6 (+ 4) % Row 2 \SetRowColor{LightBackground} \seqsplit{functional} & test if the interaction between end user and the presentation layer work well \tn % Row Count 9 (+ 3) \hhline{>{\arrayrulecolor{DarkBackground}}--} \SetRowColor{LightBackground} \mymulticolumn{2}{x{5.377cm}}{{\bf{Tests layer}} test the functionality of application core and integation between application core and outer layer.} \tn \hhline{>{\arrayrulecolor{DarkBackground}}--} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{5.377cm}{p{0.4977 cm} p{0.4977 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{5.377cm}}{\bf\textcolor{white}{Remark 01:}} \tn % Row 0 \SetRowColor{LightBackground} \mymulticolumn{2}{x{5.377cm}}{} \tn % Row Count 0 (+ 0) \hhline{>{\arrayrulecolor{DarkBackground}}--} \SetRowColor{LightBackground} \mymulticolumn{2}{x{5.377cm}}{{\bf{Application core}} is the independent core, which defines the most of core logic and a couple of interfaces, that must be implemented and used by outer layer. The inner application core should be indenpendent from outlayer, and should be always runable, if you change any part of the outer layer.} \tn \hhline{>{\arrayrulecolor{DarkBackground}}--} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{5.377cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{5.377cm}}{\bf\textcolor{white}{Key tenets of Onion}} \tn \SetRowColor{white} \mymulticolumn{1}{x{5.377cm}}{The big advantag of Onon Architecture is that business logic ends up coupled to ONLY applicaton layer concerns, not to infrastructure layer anymore. The application is built around an independent object model. Inner layers define interfaces. Outer layers implement interfaces \newline % Row Count 6 (+ 6) Direction of coupling is toward the center. All application core code can be compiled and run separate from infrastructure% Row Count 9 (+ 3) } \tn \hhline{>{\arrayrulecolor{DarkBackground}}-} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{5.377cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{5.377cm}}{\bf\textcolor{white}{Symfony Project structure: Core}} \tn \SetRowColor{LightBackground} \mymulticolumn{1}{x{5.377cm}}{Core \newline ├── Application \newline │   ├── Command \newline │   ├── Event \newline │   ├── Query \newline │   └── Service \newline └── Domain \newline ├── Event \newline ├── Model \newline ├── Repository(interfaces only) \newline ├── Service \newline └── Validation} \tn \hhline{>{\arrayrulecolor{DarkBackground}}-} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{5.377cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{5.377cm}}{\bf\textcolor{white}{Symfony Project structure: Presentation}} \tn \SetRowColor{LightBackground} \mymulticolumn{1}{x{5.377cm}}{Presentation \newline ├── Api \newline │   └── Rest \newline │   ├── Controller \newline │   └── DTO \newline │   └── SOAP \newline │   ├── Controller \newline │   └── DTO \newline ├── Console \newline │   └── Command \newline │   └── DTO \newline └── Web \newline ├── Backoffice \newline │   ├── Asset \newline │   ├── Controller \newline │   ├── DTO \newline │   ├── Form \newline │   └── Twig \newline └── Portal \newline ├── Asset \newline ├── Controller \newline     ├── DTO \newline    ├── Form \newline └── Twig} \tn \hhline{>{\arrayrulecolor{DarkBackground}}-} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{5.377cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{5.377cm}}{\bf\textcolor{white}{Symfony Project structure: Infrastructure}} \tn \SetRowColor{LightBackground} \mymulticolumn{1}{x{5.377cm}}{Infrastructure \newline ├── Mail \newline ├── Persistence \newline │   └── Doctrine \newline │   ├── Migrations \newline │   └── Repository \newline ├── Queue \newline └── SSO} \tn \hhline{>{\arrayrulecolor{DarkBackground}}-} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{5.377cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{5.377cm}}{\bf\textcolor{white}{Symfony Project structure: Tests}} \tn \SetRowColor{LightBackground} \mymulticolumn{1}{x{5.377cm}}{Tests \newline ├── functional \newline ├── integration \newline └── unit} \tn \hhline{>{\arrayrulecolor{DarkBackground}}-} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{5.377cm}{p{0.4977 cm} p{0.4977 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{5.377cm}}{\bf\textcolor{white}{Remark 02}} \tn % Row 0 \SetRowColor{LightBackground} \mymulticolumn{2}{x{5.377cm}}{} \tn % Row Count 0 (+ 0) \hhline{>{\arrayrulecolor{DarkBackground}}--} \SetRowColor{LightBackground} \mymulticolumn{2}{x{5.377cm}}{{\bf{Application layer}} should never use the concret implementation from infrastructure layer or presentation layer. It defines the application interfaces and manages the domainer interfaces, so that the application core can work a wohle without outerlayer. By providing the different application services, the communication with tests, presentation and infrastructure is possible.} \tn \hhline{>{\arrayrulecolor{DarkBackground}}--} \end{tabularx} \par\addvspace{1.3em} % That's all folks \end{multicols*} \end{document}