├── .gitignore ├── README.md ├── src ├── Scripts │ ├── Database-Create.sql │ └── Table-Course-Create.sql ├── Valhalla.Application │ ├── Abstractions │ │ ├── EntityFramework │ │ │ └── IValhallaContext.cs │ │ └── INotificationService.cs │ ├── Notifications │ │ └── Message.cs │ ├── Repositories │ │ └── ICourseReadOnlyRepository.cs │ ├── UseCases │ │ └── Courses │ │ │ └── Queries │ │ │ └── ViewAllCourses │ │ │ ├── CourseListViewModel.cs │ │ │ ├── ViewAllCoursesDapperQuery.cs │ │ │ ├── ViewAllCoursesDapperQueryHandler.cs │ │ │ ├── ViewAllCoursesQuery.cs │ │ │ ├── ViewAllCoursesQueryHandler.cs │ │ │ └── ViewAllCoursesViewModel.cs │ └── Valhalla.Application.csproj ├── Valhalla.Domain │ ├── Courses │ │ ├── Course.cs │ │ ├── CourseExceptions.cs │ │ └── CourseViewModel.cs │ ├── DomainException.cs │ ├── IEntity.cs │ └── Valhalla.Domain.csproj ├── Valhalla.Infrastructure │ ├── AutoMapper │ │ ├── AutoMapperProfile.cs │ │ ├── IHaveCustomMapping.cs │ │ ├── IMapFrom.cs │ │ ├── IMapTo.cs │ │ └── MapperProfileHelper.cs │ ├── DataAccess │ │ ├── Dapper │ │ │ ├── Entities │ │ │ │ └── Course.cs │ │ │ └── Repositories │ │ │ │ └── CourseReadOnlyRepository.cs │ │ └── EntityFramework │ │ │ ├── DesignTimeDbContextFactoryBase.cs │ │ │ ├── ValhallaContext.cs │ │ │ └── ValhallaContextFactory.cs │ ├── IoC │ │ └── Bootstrapper.cs │ ├── Services │ │ └── Notifications │ │ │ └── NotificationService.cs │ └── Valhalla.Infrastructure.csproj └── Valhalla.Web │ ├── .gitignore │ ├── BaseController.cs │ ├── ClientApp │ ├── .editorconfig │ ├── .gitignore │ ├── README.md │ ├── angular.json │ ├── browserslist │ ├── e2e │ │ ├── protractor.conf.js │ │ ├── src │ │ │ ├── app.e2e-spec.ts │ │ │ └── app.po.ts │ │ └── tsconfig.e2e.json │ ├── package-lock.json │ ├── package.json │ ├── src │ │ ├── app │ │ │ ├── app.component.html │ │ │ ├── app.component.ts │ │ │ ├── app.module.ts │ │ │ ├── app.server.module.ts │ │ │ ├── counter │ │ │ │ ├── counter.component.html │ │ │ │ ├── counter.component.spec.ts │ │ │ │ └── counter.component.ts │ │ │ ├── fetch-data │ │ │ │ ├── fetch-data.component.html │ │ │ │ └── fetch-data.component.ts │ │ │ ├── home │ │ │ │ ├── home.component.html │ │ │ │ └── home.component.ts │ │ │ └── nav-menu │ │ │ │ ├── nav-menu.component.css │ │ │ │ ├── nav-menu.component.html │ │ │ │ └── nav-menu.component.ts │ │ ├── assets │ │ │ └── .gitkeep │ │ ├── environments │ │ │ ├── environment.prod.ts │ │ │ └── environment.ts │ │ ├── index.html │ │ ├── karma.conf.js │ │ ├── main.ts │ │ ├── polyfills.ts │ │ ├── styles.css │ │ ├── test.ts │ │ ├── tsconfig.app.json │ │ ├── tsconfig.server.json │ │ ├── tsconfig.spec.json │ │ └── tslint.json │ ├── tsconfig.json │ └── tslint.json │ ├── Controllers │ └── UseCases │ │ └── Courses │ │ └── InitializeController.cs │ ├── Pages │ ├── Error.cshtml │ ├── Error.cshtml.cs │ └── _ViewImports.cshtml │ ├── Program.cs │ ├── Properties │ └── launchSettings.json │ ├── Startup.cs │ ├── Valhalla.Web.csproj │ ├── appsettings.Development.json │ ├── appsettings.json │ └── wwwroot │ └── favicon.ico ├── valhalla-logo.png └── valhalla.sln /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Mono auto generated files 17 | mono_crash.* 18 | 19 | # Build results 20 | [Dd]ebug/ 21 | [Dd]ebugPublic/ 22 | [Rr]elease/ 23 | [Rr]eleases/ 24 | x64/ 25 | x86/ 26 | [Aa][Rr][Mm]/ 27 | [Aa][Rr][Mm]64/ 28 | bld/ 29 | [Bb]in/ 30 | [Oo]bj/ 31 | [Ll]og/ 32 | [Ll]ogs/ 33 | 34 | # Visual Studio 2015/2017 cache/options directory 35 | .vs/ 36 | # Uncomment if you have tasks that create the project's static files in wwwroot 37 | #wwwroot/ 38 | 39 | # Visual Studio 2017 auto generated files 40 | Generated\ Files/ 41 | 42 | # MSTest test Results 43 | [Tt]est[Rr]esult*/ 44 | [Bb]uild[Ll]og.* 45 | 46 | # NUnit 47 | *.VisualState.xml 48 | TestResult.xml 49 | nunit-*.xml 50 | 51 | # Build Results of an ATL Project 52 | [Dd]ebugPS/ 53 | [Rr]eleasePS/ 54 | dlldata.c 55 | 56 | # Benchmark Results 57 | BenchmarkDotNet.Artifacts/ 58 | 59 | # .NET Core 60 | project.lock.json 61 | project.fragment.lock.json 62 | artifacts/ 63 | 64 | # StyleCop 65 | StyleCopReport.xml 66 | 67 | # Files built by Visual Studio 68 | *_i.c 69 | *_p.c 70 | *_h.h 71 | *.ilk 72 | *.meta 73 | *.obj 74 | *.iobj 75 | *.pch 76 | *.pdb 77 | *.ipdb 78 | *.pgc 79 | *.pgd 80 | *.rsp 81 | *.sbr 82 | *.tlb 83 | *.tli 84 | *.tlh 85 | *.tmp 86 | *.tmp_proj 87 | *_wpftmp.csproj 88 | *.log 89 | *.vspscc 90 | *.vssscc 91 | .builds 92 | *.pidb 93 | *.svclog 94 | *.scc 95 | 96 | # Chutzpah Test files 97 | _Chutzpah* 98 | 99 | # Visual C++ cache files 100 | ipch/ 101 | *.aps 102 | *.ncb 103 | *.opendb 104 | *.opensdf 105 | *.sdf 106 | *.cachefile 107 | *.VC.db 108 | *.VC.VC.opendb 109 | 110 | # Visual Studio profiler 111 | *.psess 112 | *.vsp 113 | *.vspx 114 | *.sap 115 | 116 | # Visual Studio Trace Files 117 | *.e2e 118 | 119 | # TFS 2012 Local Workspace 120 | $tf/ 121 | 122 | # Guidance Automation Toolkit 123 | *.gpState 124 | 125 | # ReSharper is a .NET coding add-in 126 | _ReSharper*/ 127 | *.[Rr]e[Ss]harper 128 | *.DotSettings.user 129 | 130 | # TeamCity is a build add-in 131 | _TeamCity* 132 | 133 | # DotCover is a Code Coverage Tool 134 | *.dotCover 135 | 136 | # AxoCover is a Code Coverage Tool 137 | .axoCover/* 138 | !.axoCover/settings.json 139 | 140 | # Visual Studio code coverage results 141 | *.coverage 142 | *.coveragexml 143 | 144 | # NCrunch 145 | _NCrunch_* 146 | .*crunch*.local.xml 147 | nCrunchTemp_* 148 | 149 | # MightyMoose 150 | *.mm.* 151 | AutoTest.Net/ 152 | 153 | # Web workbench (sass) 154 | .sass-cache/ 155 | 156 | # Installshield output folder 157 | [Ee]xpress/ 158 | 159 | # DocProject is a documentation generator add-in 160 | DocProject/buildhelp/ 161 | DocProject/Help/*.HxT 162 | DocProject/Help/*.HxC 163 | DocProject/Help/*.hhc 164 | DocProject/Help/*.hhk 165 | DocProject/Help/*.hhp 166 | DocProject/Help/Html2 167 | DocProject/Help/html 168 | 169 | # Click-Once directory 170 | publish/ 171 | 172 | # Publish Web Output 173 | *.[Pp]ublish.xml 174 | *.azurePubxml 175 | # Note: Comment the next line if you want to checkin your web deploy settings, 176 | # but database connection strings (with potential passwords) will be unencrypted 177 | *.pubxml 178 | *.publishproj 179 | 180 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 181 | # checkin your Azure Web App publish settings, but sensitive information contained 182 | # in these scripts will be unencrypted 183 | PublishScripts/ 184 | 185 | # NuGet Packages 186 | *.nupkg 187 | # NuGet Symbol Packages 188 | *.snupkg 189 | # The packages folder can be ignored because of Package Restore 190 | **/[Pp]ackages/* 191 | # except build/, which is used as an MSBuild target. 192 | !**/[Pp]ackages/build/ 193 | # Uncomment if necessary however generally it will be regenerated when needed 194 | #!**/[Pp]ackages/repositories.config 195 | # NuGet v3's project.json files produces more ignorable files 196 | *.nuget.props 197 | *.nuget.targets 198 | 199 | # Microsoft Azure Build Output 200 | csx/ 201 | *.build.csdef 202 | 203 | # Microsoft Azure Emulator 204 | ecf/ 205 | rcf/ 206 | 207 | # Windows Store app package directories and files 208 | AppPackages/ 209 | BundleArtifacts/ 210 | Package.StoreAssociation.xml 211 | _pkginfo.txt 212 | *.appx 213 | *.appxbundle 214 | *.appxupload 215 | 216 | # Visual Studio cache files 217 | # files ending in .cache can be ignored 218 | *.[Cc]ache 219 | # but keep track of directories ending in .cache 220 | !?*.[Cc]ache/ 221 | 222 | # Others 223 | ClientBin/ 224 | ~$* 225 | *~ 226 | *.dbmdl 227 | *.dbproj.schemaview 228 | *.jfm 229 | *.pfx 230 | *.publishsettings 231 | orleans.codegen.cs 232 | 233 | # Including strong name files can present a security risk 234 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 235 | #*.snk 236 | 237 | # Since there are multiple workflows, uncomment next line to ignore bower_components 238 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 239 | #bower_components/ 240 | 241 | # RIA/Silverlight projects 242 | Generated_Code/ 243 | 244 | # Backup & report files from converting an old project file 245 | # to a newer Visual Studio version. Backup files are not needed, 246 | # because we have git ;-) 247 | _UpgradeReport_Files/ 248 | Backup*/ 249 | UpgradeLog*.XML 250 | UpgradeLog*.htm 251 | ServiceFabricBackup/ 252 | *.rptproj.bak 253 | 254 | # SQL Server files 255 | *.mdf 256 | *.ldf 257 | *.ndf 258 | 259 | # Business Intelligence projects 260 | *.rdl.data 261 | *.bim.layout 262 | *.bim_*.settings 263 | *.rptproj.rsuser 264 | *- [Bb]ackup.rdl 265 | *- [Bb]ackup ([0-9]).rdl 266 | *- [Bb]ackup ([0-9][0-9]).rdl 267 | 268 | # Microsoft Fakes 269 | FakesAssemblies/ 270 | 271 | # GhostDoc plugin setting file 272 | *.GhostDoc.xml 273 | 274 | # Node.js Tools for Visual Studio 275 | .ntvs_analysis.dat 276 | node_modules/ 277 | 278 | # Visual Studio 6 build log 279 | *.plg 280 | 281 | # Visual Studio 6 workspace options file 282 | *.opt 283 | 284 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 285 | *.vbw 286 | 287 | # Visual Studio LightSwitch build output 288 | **/*.HTMLClient/GeneratedArtifacts 289 | **/*.DesktopClient/GeneratedArtifacts 290 | **/*.DesktopClient/ModelManifest.xml 291 | **/*.Server/GeneratedArtifacts 292 | **/*.Server/ModelManifest.xml 293 | _Pvt_Extensions 294 | 295 | # Paket dependency manager 296 | .paket/paket.exe 297 | paket-files/ 298 | 299 | # FAKE - F# Make 300 | .fake/ 301 | 302 | # CodeRush personal settings 303 | .cr/personal 304 | 305 | # Python Tools for Visual Studio (PTVS) 306 | __pycache__/ 307 | *.pyc 308 | 309 | # Cake - Uncomment if you are using it 310 | # tools/** 311 | # !tools/packages.config 312 | 313 | # Tabs Studio 314 | *.tss 315 | 316 | # Telerik's JustMock configuration file 317 | *.jmconfig 318 | 319 | # BizTalk build output 320 | *.btp.cs 321 | *.btm.cs 322 | *.odx.cs 323 | *.xsd.cs 324 | 325 | # OpenCover UI analysis results 326 | OpenCover/ 327 | 328 | # Azure Stream Analytics local run output 329 | ASALocalRun/ 330 | 331 | # MSBuild Binary and Structured Log 332 | *.binlog 333 | 334 | # NVidia Nsight GPU debugger configuration file 335 | *.nvuser 336 | 337 | # MFractors (Xamarin productivity tool) working folder 338 | .mfractor/ 339 | 340 | # Local History for Visual Studio 341 | .localhistory/ 342 | 343 | # BeatPulse healthcheck temp database 344 | healthchecksdb 345 | 346 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 347 | MigrationBackup/ 348 | 349 | # Ionide (cross platform F# VS Code tools) working folder 350 | .ionide/ 351 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | Esse repositório é uma implementação de uma Arquitetura Clean (Clean Architecture) usando .NET Core. 4 | 5 | O foco é ter um estudo de caso e uma arquitetura base onde você consiga entender a importância de ter uma aplicação desacoplada de frameworks e tecnologias de uma forma que seu software represente mais o contexto de negócio que você está inserido(a) e não uma implementação baseada em regras de negócios de banco de dados. 6 | 7 | ## Tecnologias 8 | * .NET Core 3.1 9 | * Entity Framework Core 3.1 10 | * Dapper 11 | * Angular 8 12 | 13 | ## Sobre Clean Architecture e suas responsabilidades 14 | 15 | ### Domínio (Domain) 16 | 17 | Essa camada é responsável por todas as suas entidades, enumerações, exceções, abstrações (interfaces por exemplo), tipos e lógicas específicas ao seu domínio. 18 | 19 | ### Aplicação (Application) 20 | 21 | Essa camada é responsável por toda lógica da sua aplicação. Ela depende da camada de domínio mas não tem dependência com nenhuma outra camada ou projeto. Essa camada descreve abstrações que são implementadas nas camadas de fora. 22 | 23 | Se por acaso você precisar implementar um acesso a dados, por exemplo o Entity Framework, essa implementação ficaria fora dessa camada (em infraestrutura), porém a abstração seria implementada aqui. 24 | 25 | ### Infraestrutura (Infrastructure) 26 | 27 | Essa camada é responsável por conter classes que acessem recursos externos a nossa aplicação, como por exemplo web services, emails ou até mesmo acesso a disco. Essas classes devem implementar abstrações da camada de aplicação. 28 | 29 | ### Interface de Usuário (UI) 30 | 31 | Essa camada é responsável pela interface de usuário, no caso desse projeto temos um exemplo simples utilizando Angular 8 e ASP.NET Core 3. Essa camada depende da aplicação e infraestrutura porém toda dependência que vier de infraestrutura é apenas para consumir injeção de dependências. 32 | 33 | ## Suporte 34 | 35 | Se você quiser participar ou encontrar problemas, abra um issue [aqui](https://github.com/rcarneironet/valhalla-clean-architecture/issues/new). 36 | 37 | Se de alguma forma o projeto foi útil para você ou sua empresa, dê uma estrela e siga o projeto! 38 | 39 | 40 | -------------------------------------------------------------------------------- /src/Scripts/Database-Create.sql: -------------------------------------------------------------------------------- 1 | USE [master] 2 | GO 3 | 4 | /****** Object: Database [ValhallaDatabase] Script Date: 07/02/2020 17:05:32 ******/ 5 | CREATE DATABASE [ValhallaDatabase] 6 | CONTAINMENT = NONE 7 | ON PRIMARY 8 | ( NAME = N'ValhallaDatabase', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL14.MSSQLSERVER17\MSSQL\DATA\ValhallaDatabase.mdf' , SIZE = 8192KB , MAXSIZE = UNLIMITED, FILEGROWTH = 65536KB ) 9 | LOG ON 10 | ( NAME = N'ValhallaDatabase_log', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL14.MSSQLSERVER17\MSSQL\DATA\ValhallaDatabase_log.ldf' , SIZE = 8192KB , MAXSIZE = 2048GB , FILEGROWTH = 65536KB ) 11 | GO 12 | 13 | ALTER DATABASE [ValhallaDatabase] SET COMPATIBILITY_LEVEL = 140 14 | GO 15 | 16 | IF (1 = FULLTEXTSERVICEPROPERTY('IsFullTextInstalled')) 17 | begin 18 | EXEC [ValhallaDatabase].[dbo].[sp_fulltext_database] @action = 'enable' 19 | end 20 | GO 21 | 22 | ALTER DATABASE [ValhallaDatabase] SET ANSI_NULL_DEFAULT OFF 23 | GO 24 | 25 | ALTER DATABASE [ValhallaDatabase] SET ANSI_NULLS OFF 26 | GO 27 | 28 | ALTER DATABASE [ValhallaDatabase] SET ANSI_PADDING OFF 29 | GO 30 | 31 | ALTER DATABASE [ValhallaDatabase] SET ANSI_WARNINGS OFF 32 | GO 33 | 34 | ALTER DATABASE [ValhallaDatabase] SET ARITHABORT OFF 35 | GO 36 | 37 | ALTER DATABASE [ValhallaDatabase] SET AUTO_CLOSE OFF 38 | GO 39 | 40 | ALTER DATABASE [ValhallaDatabase] SET AUTO_SHRINK OFF 41 | GO 42 | 43 | ALTER DATABASE [ValhallaDatabase] SET AUTO_UPDATE_STATISTICS ON 44 | GO 45 | 46 | ALTER DATABASE [ValhallaDatabase] SET CURSOR_CLOSE_ON_COMMIT OFF 47 | GO 48 | 49 | ALTER DATABASE [ValhallaDatabase] SET CURSOR_DEFAULT GLOBAL 50 | GO 51 | 52 | ALTER DATABASE [ValhallaDatabase] SET CONCAT_NULL_YIELDS_NULL OFF 53 | GO 54 | 55 | ALTER DATABASE [ValhallaDatabase] SET NUMERIC_ROUNDABORT OFF 56 | GO 57 | 58 | ALTER DATABASE [ValhallaDatabase] SET QUOTED_IDENTIFIER OFF 59 | GO 60 | 61 | ALTER DATABASE [ValhallaDatabase] SET RECURSIVE_TRIGGERS OFF 62 | GO 63 | 64 | ALTER DATABASE [ValhallaDatabase] SET DISABLE_BROKER 65 | GO 66 | 67 | ALTER DATABASE [ValhallaDatabase] SET AUTO_UPDATE_STATISTICS_ASYNC OFF 68 | GO 69 | 70 | ALTER DATABASE [ValhallaDatabase] SET DATE_CORRELATION_OPTIMIZATION OFF 71 | GO 72 | 73 | ALTER DATABASE [ValhallaDatabase] SET TRUSTWORTHY OFF 74 | GO 75 | 76 | ALTER DATABASE [ValhallaDatabase] SET ALLOW_SNAPSHOT_ISOLATION OFF 77 | GO 78 | 79 | ALTER DATABASE [ValhallaDatabase] SET PARAMETERIZATION SIMPLE 80 | GO 81 | 82 | ALTER DATABASE [ValhallaDatabase] SET READ_COMMITTED_SNAPSHOT OFF 83 | GO 84 | 85 | ALTER DATABASE [ValhallaDatabase] SET HONOR_BROKER_PRIORITY OFF 86 | GO 87 | 88 | ALTER DATABASE [ValhallaDatabase] SET RECOVERY FULL 89 | GO 90 | 91 | ALTER DATABASE [ValhallaDatabase] SET MULTI_USER 92 | GO 93 | 94 | ALTER DATABASE [ValhallaDatabase] SET PAGE_VERIFY CHECKSUM 95 | GO 96 | 97 | ALTER DATABASE [ValhallaDatabase] SET DB_CHAINING OFF 98 | GO 99 | 100 | ALTER DATABASE [ValhallaDatabase] SET FILESTREAM( NON_TRANSACTED_ACCESS = OFF ) 101 | GO 102 | 103 | ALTER DATABASE [ValhallaDatabase] SET TARGET_RECOVERY_TIME = 60 SECONDS 104 | GO 105 | 106 | ALTER DATABASE [ValhallaDatabase] SET DELAYED_DURABILITY = DISABLED 107 | GO 108 | 109 | ALTER DATABASE [ValhallaDatabase] SET QUERY_STORE = OFF 110 | GO 111 | 112 | ALTER DATABASE [ValhallaDatabase] SET READ_WRITE 113 | GO 114 | 115 | 116 | -------------------------------------------------------------------------------- /src/Scripts/Table-Course-Create.sql: -------------------------------------------------------------------------------- 1 | USE [ValhallaDatabase] 2 | GO 3 | 4 | /****** Object: Table [dbo].[Course] Script Date: 07/02/2020 17:06:24 ******/ 5 | SET ANSI_NULLS ON 6 | GO 7 | 8 | SET QUOTED_IDENTIFIER ON 9 | GO 10 | 11 | CREATE TABLE [dbo].[Course]( 12 | [Id] [uniqueidentifier] NOT NULL, 13 | [Name] [varchar](50) NOT NULL, 14 | [Created] [datetime] NOT NULL, 15 | [Updated] [datetime] NULL 16 | ) ON [PRIMARY] 17 | GO 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/Valhalla.Application/Abstractions/EntityFramework/IValhallaContext.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore; 2 | using Valhalla.Domain.Courses; 3 | 4 | namespace Valhalla.Application.Abstractions.EntityFramework 5 | { 6 | public interface IValhallaContext 7 | { 8 | DbSet Course { get; set; } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/Valhalla.Application/Abstractions/INotificationService.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using Valhalla.Application.Notifications; 3 | 4 | namespace Valhalla.Application.Abstractions 5 | { 6 | public interface INotificationService 7 | { 8 | Task SendAsync(Message message); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/Valhalla.Application/Notifications/Message.cs: -------------------------------------------------------------------------------- 1 | namespace Valhalla.Application.Notifications 2 | { 3 | public class Message 4 | { 5 | public string From { get; set; } 6 | public string To { get; set; } 7 | public string Subject { get; set; } 8 | public string Body { get; set; } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/Valhalla.Application/Repositories/ICourseReadOnlyRepository.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Threading.Tasks; 3 | using Valhalla.Domain.Courses; 4 | 5 | namespace Valhalla.Application.Repositories 6 | { 7 | public interface ICourseReadOnlyRepository 8 | { 9 | Task> List(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/Valhalla.Application/UseCases/Courses/Queries/ViewAllCourses/CourseListViewModel.cs: -------------------------------------------------------------------------------- 1 | namespace Valhalla.Application.UseCases.Courses.Queries.ViewAllCourses 2 | { 3 | public class CourseListViewModel 4 | { 5 | public string Name { get; set; } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/Valhalla.Application/UseCases/Courses/Queries/ViewAllCourses/ViewAllCoursesDapperQuery.cs: -------------------------------------------------------------------------------- 1 | using MediatR; 2 | 3 | namespace Valhalla.Application.UseCases.Courses.Queries.ViewAllCourses 4 | { 5 | public class ViewAllCoursesDapperQuery : IRequest 6 | { 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/Valhalla.Application/UseCases/Courses/Queries/ViewAllCourses/ViewAllCoursesDapperQueryHandler.cs: -------------------------------------------------------------------------------- 1 | using MediatR; 2 | using System.Threading; 3 | using System.Threading.Tasks; 4 | using Valhalla.Application.Repositories; 5 | 6 | namespace Valhalla.Application.UseCases.Courses.Queries.ViewAllCourses 7 | { 8 | public class ViewAllCoursesDapperQueryHandler : IRequestHandler 9 | { 10 | private readonly ICourseReadOnlyRepository _courseRepository; 11 | 12 | public ViewAllCoursesDapperQueryHandler(ICourseReadOnlyRepository courseRepository) 13 | { 14 | _courseRepository = courseRepository; 15 | } 16 | 17 | public async Task Handle( 18 | ViewAllCoursesDapperQuery request, 19 | CancellationToken cancellationToken) 20 | { 21 | return new ViewAllCoursesViewModel 22 | { 23 | Courses = await _courseRepository.List() 24 | }; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Valhalla.Application/UseCases/Courses/Queries/ViewAllCourses/ViewAllCoursesQuery.cs: -------------------------------------------------------------------------------- 1 | using MediatR; 2 | 3 | namespace Valhalla.Application.UseCases.Courses.Queries.ViewAllCourses 4 | { 5 | public class ViewAllCoursesQuery : IRequest 6 | { 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/Valhalla.Application/UseCases/Courses/Queries/ViewAllCourses/ViewAllCoursesQueryHandler.cs: -------------------------------------------------------------------------------- 1 | using MediatR; 2 | using Microsoft.EntityFrameworkCore; 3 | using System.Threading; 4 | using System.Threading.Tasks; 5 | using Valhalla.Application.Abstractions.EntityFramework; 6 | 7 | namespace Valhalla.Application.UseCases.Courses.Queries.ViewAllCourses 8 | { 9 | public class ViewAllCoursesQueryHandler : IRequestHandler 10 | { 11 | private readonly IValhallaContext _context; 12 | 13 | public ViewAllCoursesQueryHandler( 14 | IValhallaContext context) 15 | { 16 | _context = context; 17 | } 18 | 19 | public async Task Handle( 20 | ViewAllCoursesQuery request, 21 | CancellationToken cancellationToken) 22 | { 23 | 24 | return new ViewAllCoursesViewModel 25 | { 26 | Courses = await _context.Course 27 | .ToListAsync(cancellationToken) 28 | }; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Valhalla.Application/UseCases/Courses/Queries/ViewAllCourses/ViewAllCoursesViewModel.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Valhalla.Domain.Courses; 3 | 4 | namespace Valhalla.Application.UseCases.Courses.Queries.ViewAllCourses 5 | { 6 | public class ViewAllCoursesViewModel 7 | { 8 | public IEnumerable Courses { get; set; } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/Valhalla.Application/Valhalla.Application.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/Valhalla.Domain/Courses/Course.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Valhalla.Domain.Courses 4 | { 5 | public class Course : IEntity 6 | { 7 | public Guid Id { get; private set; } 8 | public string Name { get; private set; } 9 | public DateTime Created { get; private set; } 10 | public DateTime? Updated { get; private set; } 11 | 12 | public Course() 13 | { 14 | } 15 | public void Register(string name) 16 | { 17 | Id = Guid.NewGuid(); 18 | Name = name; 19 | Created = DateTime.UtcNow; 20 | } 21 | 22 | public void ChangeName(CourseViewModel course) 23 | { 24 | if (string.IsNullOrEmpty(course.Name)) 25 | { 26 | throw new CourseExceptions($"Course name cannot be null or empty!"); 27 | } 28 | 29 | Name = course.Name; 30 | Updated = DateTime.UtcNow; 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Valhalla.Domain/Courses/CourseExceptions.cs: -------------------------------------------------------------------------------- 1 | namespace Valhalla.Domain.Courses 2 | { 3 | public sealed class CourseExceptions : DomainException 4 | { 5 | internal CourseExceptions(string businessExceptionMessage) 6 | : base(businessExceptionMessage) 7 | { } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/Valhalla.Domain/Courses/CourseViewModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Valhalla.Domain.Courses 4 | { 5 | public sealed class CourseViewModel 6 | { 7 | public Guid Id { get; private set; } 8 | public string Name { get; private set; } 9 | 10 | public CourseViewModel(Guid id, string name) 11 | { 12 | Id = id; 13 | Name = name; 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/Valhalla.Domain/DomainException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Valhalla.Domain 4 | { 5 | public class DomainException : Exception 6 | { 7 | internal DomainException(string businessExceptionMessage) 8 | : base(businessExceptionMessage) 9 | { 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/Valhalla.Domain/IEntity.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Valhalla.Domain 4 | { 5 | internal interface IEntity 6 | { 7 | Guid Id { get; } 8 | DateTime Created { get; } 9 | DateTime? Updated { get; } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/Valhalla.Domain/Valhalla.Domain.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/Valhalla.Infrastructure/AutoMapper/AutoMapperProfile.cs: -------------------------------------------------------------------------------- 1 | using AutoMapper; 2 | using System.Reflection; 3 | 4 | namespace Valhalla.Infrastructure.AutoMapper 5 | { 6 | public class AutoMapperProfile : Profile 7 | { 8 | public AutoMapperProfile() 9 | { 10 | LoadStandardMappings(); 11 | LoadCustomMappings(); 12 | } 13 | 14 | private void LoadStandardMappings() 15 | { 16 | var mapsFrom = MapperProfileHelper.LoadStandardMappings(Assembly.GetExecutingAssembly()); 17 | 18 | foreach (var map in mapsFrom) 19 | { 20 | CreateMap(map.Source, map.Destination).ReverseMap(); 21 | } 22 | } 23 | 24 | private void LoadCustomMappings() 25 | { 26 | var mapsFrom = MapperProfileHelper.LoadCustomMappings(Assembly.GetExecutingAssembly()); 27 | 28 | foreach (var map in mapsFrom) 29 | { 30 | map.CreateMappings(this); 31 | } 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/Valhalla.Infrastructure/AutoMapper/IHaveCustomMapping.cs: -------------------------------------------------------------------------------- 1 | using AutoMapper; 2 | 3 | namespace Valhalla.Infrastructure.AutoMapper 4 | { 5 | public interface IHaveCustomMapping 6 | { 7 | void CreateMappings(Profile configuration); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/Valhalla.Infrastructure/AutoMapper/IMapFrom.cs: -------------------------------------------------------------------------------- 1 | namespace Valhalla.Infrastructure.AutoMapper 2 | { 3 | public interface IMapFrom 4 | { 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/Valhalla.Infrastructure/AutoMapper/IMapTo.cs: -------------------------------------------------------------------------------- 1 | namespace Valhalla.Infrastructure.AutoMapper 2 | { 3 | public interface IMapTo 4 | { 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/Valhalla.Infrastructure/AutoMapper/MapperProfileHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Reflection; 5 | 6 | namespace Valhalla.Infrastructure.AutoMapper 7 | { 8 | public sealed class Map 9 | { 10 | public Type Source { get; set; } 11 | public Type Destination { get; set; } 12 | } 13 | 14 | public static class MapperProfileHelper 15 | { 16 | public static IList LoadStandardMappings(Assembly rootAssembly) 17 | { 18 | var types = rootAssembly.GetExportedTypes(); 19 | 20 | var mapsFrom = ( 21 | from type in types 22 | from instance in type.GetInterfaces() 23 | where 24 | instance.IsGenericType && instance.GetGenericTypeDefinition() == typeof(IMapFrom<>) && 25 | !type.IsAbstract && 26 | !type.IsInterface 27 | select new Map 28 | { 29 | Source = type.GetInterfaces().First().GetGenericArguments().First(), 30 | Destination = type 31 | }).ToList(); 32 | 33 | return mapsFrom; 34 | } 35 | 36 | public static IList LoadCustomMappings(Assembly rootAssembly) 37 | { 38 | var types = rootAssembly.GetExportedTypes(); 39 | 40 | var mapsFrom = ( 41 | from type in types 42 | from instance in type.GetInterfaces() 43 | where 44 | typeof(IHaveCustomMapping).IsAssignableFrom(type) && 45 | !type.IsAbstract && 46 | !type.IsInterface 47 | select (IHaveCustomMapping)Activator.CreateInstance(type)).ToList(); 48 | 49 | return mapsFrom; 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/Valhalla.Infrastructure/DataAccess/Dapper/Entities/Course.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Valhalla.Infrastructure.DataAccess.Dapper.Entities 4 | { 5 | public class Course 6 | { 7 | public Guid Id { get; set; } 8 | public string Name { get; set; } 9 | public DateTime Created { get; set; } 10 | public DateTime? Updated { get; set; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/Valhalla.Infrastructure/DataAccess/Dapper/Repositories/CourseReadOnlyRepository.cs: -------------------------------------------------------------------------------- 1 | using Dapper; 2 | using Microsoft.Data.SqlClient; 3 | using System.Collections.Generic; 4 | using System.Data; 5 | using System.Threading.Tasks; 6 | using Valhalla.Application.Repositories; 7 | using Valhalla.Domain.Courses; 8 | 9 | namespace Valhalla.Infrastructure.DataAccess.Dapper.Repositories 10 | { 11 | public class CourseReadOnlyRepository : ICourseReadOnlyRepository 12 | { 13 | //just for test purpose, consider using DI for this 14 | private readonly string connectionString = @"Data Source=OFFICEWS;Initial Catalog=ValhallaDatabase;Integrated Security=True"; 15 | 16 | public async Task> List() 17 | { 18 | using (IDbConnection db = new SqlConnection(connectionString)) 19 | { 20 | string accountSQL = @"SELECT * FROM [dbo].[Course] with (NOLOCK)"; 21 | return await db.QueryAsync(accountSQL); 22 | } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Valhalla.Infrastructure/DataAccess/EntityFramework/DesignTimeDbContextFactoryBase.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore; 2 | using Microsoft.EntityFrameworkCore.Design; 3 | using Microsoft.Extensions.Configuration; 4 | using System; 5 | using System.IO; 6 | 7 | namespace Valhalla.Infrastructure.DataAccess.EntityFramework 8 | { 9 | public abstract class DesignTimeDbContextFactoryBase : 10 | IDesignTimeDbContextFactory where TContext : DbContext 11 | { 12 | private const string ConnectionStringName = "ValhallaDatabase"; 13 | private const string AspNetCoreEnvironment = "ASPNETCORE_ENVIRONMENT"; 14 | 15 | public TContext CreateDbContext(string[] args) 16 | { 17 | var basePath = Directory.GetCurrentDirectory() + string.Format("{0}..{0}Valhalla.Web", Path.DirectorySeparatorChar); 18 | return Create(basePath, Environment.GetEnvironmentVariable(AspNetCoreEnvironment)); 19 | } 20 | 21 | protected abstract TContext CreateNewInstance(DbContextOptions options); 22 | 23 | private TContext Create(string basePath, string environmentName) 24 | { 25 | 26 | var configuration = new ConfigurationBuilder() 27 | .SetBasePath(basePath) 28 | .AddJsonFile("appsettings.json") 29 | .AddJsonFile($"appsettings.Local.json", optional: true) 30 | .AddJsonFile($"appsettings.{environmentName}.json", optional: true) 31 | .AddEnvironmentVariables() 32 | .Build(); 33 | 34 | var connectionString = configuration.GetConnectionString(ConnectionStringName); 35 | 36 | return Create(connectionString); 37 | } 38 | 39 | private TContext Create(string connectionString) 40 | { 41 | if (string.IsNullOrEmpty(connectionString)) 42 | { 43 | throw new ArgumentException($"Connection string '{ConnectionStringName}' is null or empty.", nameof(connectionString)); 44 | } 45 | 46 | Console.WriteLine($"DesignTimeDbContextFactoryBase.Create(string): Connection string: '{connectionString}'."); 47 | 48 | var optionsBuilder = new DbContextOptionsBuilder(); 49 | 50 | optionsBuilder.UseSqlServer(connectionString); 51 | 52 | return CreateNewInstance(optionsBuilder.Options); 53 | } 54 | } 55 | } -------------------------------------------------------------------------------- /src/Valhalla.Infrastructure/DataAccess/EntityFramework/ValhallaContext.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore; 2 | using Valhalla.Application.Abstractions.EntityFramework; 3 | using Valhalla.Domain.Courses; 4 | 5 | namespace Valhalla.Infrastructure.DataAccess.EntityFramework 6 | { 7 | public class ValhallaContext : DbContext, IValhallaContext 8 | { 9 | public ValhallaContext(DbContextOptions options) 10 | : base(options) 11 | { 12 | } 13 | public DbSet Course { get; set; } 14 | protected override void OnModelCreating(ModelBuilder modelBuilder) 15 | { 16 | modelBuilder.ApplyConfigurationsFromAssembly(typeof(ValhallaContext).Assembly); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Valhalla.Infrastructure/DataAccess/EntityFramework/ValhallaContextFactory.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore; 2 | 3 | namespace Valhalla.Infrastructure.DataAccess.EntityFramework 4 | { 5 | public class ValhallaContextFactory : DesignTimeDbContextFactoryBase 6 | { 7 | protected override ValhallaContext CreateNewInstance(DbContextOptions options) 8 | { 9 | return new ValhallaContext(options); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/Valhalla.Infrastructure/IoC/Bootstrapper.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.DependencyInjection; 2 | using Valhalla.Application.Abstractions; 3 | using Valhalla.Application.Repositories; 4 | using Valhalla.Infrastructure.DataAccess.Dapper.Repositories; 5 | using Valhalla.Infrastructure.Services.Notifications; 6 | 7 | namespace Valhalla.Infrastructure.IoC 8 | { 9 | public static class Bootstrapper 10 | { 11 | public static void RegisterRepositoryServices(this IServiceCollection services) 12 | { 13 | services.AddTransient(); 14 | services.AddScoped(); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/Valhalla.Infrastructure/Services/Notifications/NotificationService.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using Valhalla.Application.Abstractions; 3 | using Valhalla.Application.Notifications; 4 | 5 | namespace Valhalla.Infrastructure.Services.Notifications 6 | { 7 | public class NotificationService : INotificationService 8 | { 9 | public Task SendAsync(Message message) 10 | { 11 | //to-do: Implement send message here 12 | return Task.CompletedTask; 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Valhalla.Infrastructure/Valhalla.Infrastructure.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | all 13 | runtime; build; native; contentfiles; analyzers; buildtransitive 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /src/Valhalla.Web/.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | x64/ 19 | x86/ 20 | build/ 21 | bld/ 22 | bin/ 23 | Bin/ 24 | obj/ 25 | Obj/ 26 | 27 | # Visual Studio 2015 cache/options directory 28 | .vs/ 29 | 30 | # MSTest test Results 31 | [Tt]est[Rr]esult*/ 32 | [Bb]uild[Ll]og.* 33 | 34 | # NUNIT 35 | *.VisualState.xml 36 | TestResult.xml 37 | 38 | # Build Results of an ATL Project 39 | [Dd]ebugPS/ 40 | [Rr]eleasePS/ 41 | dlldata.c 42 | 43 | *_i.c 44 | *_p.c 45 | *_i.h 46 | *.ilk 47 | *.meta 48 | *.obj 49 | *.pch 50 | *.pdb 51 | *.pgc 52 | *.pgd 53 | *.rsp 54 | *.sbr 55 | *.tlb 56 | *.tli 57 | *.tlh 58 | *.tmp 59 | *.tmp_proj 60 | *.log 61 | *.vspscc 62 | *.vssscc 63 | .builds 64 | *.pidb 65 | *.svclog 66 | *.scc 67 | 68 | # Chutzpah Test files 69 | _Chutzpah* 70 | 71 | # Visual C++ cache files 72 | ipch/ 73 | *.aps 74 | *.ncb 75 | *.opendb 76 | *.opensdf 77 | *.sdf 78 | *.cachefile 79 | 80 | # Visual Studio profiler 81 | *.psess 82 | *.vsp 83 | *.vspx 84 | *.sap 85 | 86 | # TFS 2012 Local Workspace 87 | $tf/ 88 | 89 | # Guidance Automation Toolkit 90 | *.gpState 91 | 92 | # ReSharper is a .NET coding add-in 93 | _ReSharper*/ 94 | *.[Rr]e[Ss]harper 95 | *.DotSettings.user 96 | 97 | # JustCode is a .NET coding add-in 98 | .JustCode 99 | 100 | # TeamCity is a build add-in 101 | _TeamCity* 102 | 103 | # DotCover is a Code Coverage Tool 104 | *.dotCover 105 | 106 | # NCrunch 107 | _NCrunch_* 108 | .*crunch*.local.xml 109 | nCrunchTemp_* 110 | 111 | # MightyMoose 112 | *.mm.* 113 | AutoTest.Net/ 114 | 115 | # Web workbench (sass) 116 | .sass-cache/ 117 | 118 | # Installshield output folder 119 | [Ee]xpress/ 120 | 121 | # DocProject is a documentation generator add-in 122 | DocProject/buildhelp/ 123 | DocProject/Help/*.HxT 124 | DocProject/Help/*.HxC 125 | DocProject/Help/*.hhc 126 | DocProject/Help/*.hhk 127 | DocProject/Help/*.hhp 128 | DocProject/Help/Html2 129 | DocProject/Help/html 130 | 131 | # Click-Once directory 132 | publish/ 133 | 134 | # Publish Web Output 135 | *.[Pp]ublish.xml 136 | *.azurePubxml 137 | # TODO: Comment the next line if you want to checkin your web deploy settings 138 | # but database connection strings (with potential passwords) will be unencrypted 139 | *.pubxml 140 | *.publishproj 141 | 142 | # NuGet Packages 143 | *.nupkg 144 | # The packages folder can be ignored because of Package Restore 145 | **/packages/* 146 | # except build/, which is used as an MSBuild target. 147 | !**/packages/build/ 148 | # Uncomment if necessary however generally it will be regenerated when needed 149 | #!**/packages/repositories.config 150 | 151 | # Microsoft Azure Build Output 152 | csx/ 153 | *.build.csdef 154 | 155 | # Microsoft Azure Emulator 156 | ecf/ 157 | rcf/ 158 | 159 | # Microsoft Azure ApplicationInsights config file 160 | ApplicationInsights.config 161 | 162 | # Windows Store app package directory 163 | AppPackages/ 164 | BundleArtifacts/ 165 | 166 | # Visual Studio cache files 167 | # files ending in .cache can be ignored 168 | *.[Cc]ache 169 | # but keep track of directories ending in .cache 170 | !*.[Cc]ache/ 171 | 172 | # Others 173 | ClientBin/ 174 | ~$* 175 | *~ 176 | *.dbmdl 177 | *.dbproj.schemaview 178 | *.pfx 179 | *.publishsettings 180 | orleans.codegen.cs 181 | 182 | /node_modules 183 | 184 | # RIA/Silverlight projects 185 | Generated_Code/ 186 | 187 | # Backup & report files from converting an old project file 188 | # to a newer Visual Studio version. Backup files are not needed, 189 | # because we have git ;-) 190 | _UpgradeReport_Files/ 191 | Backup*/ 192 | UpgradeLog*.XML 193 | UpgradeLog*.htm 194 | 195 | # SQL Server files 196 | *.mdf 197 | *.ldf 198 | 199 | # Business Intelligence projects 200 | *.rdl.data 201 | *.bim.layout 202 | *.bim_*.settings 203 | 204 | # Microsoft Fakes 205 | FakesAssemblies/ 206 | 207 | # GhostDoc plugin setting file 208 | *.GhostDoc.xml 209 | 210 | # Node.js Tools for Visual Studio 211 | .ntvs_analysis.dat 212 | 213 | # Visual Studio 6 build log 214 | *.plg 215 | 216 | # Visual Studio 6 workspace options file 217 | *.opt 218 | 219 | # Visual Studio LightSwitch build output 220 | **/*.HTMLClient/GeneratedArtifacts 221 | **/*.DesktopClient/GeneratedArtifacts 222 | **/*.DesktopClient/ModelManifest.xml 223 | **/*.Server/GeneratedArtifacts 224 | **/*.Server/ModelManifest.xml 225 | _Pvt_Extensions 226 | 227 | # Paket dependency manager 228 | .paket/paket.exe 229 | 230 | # FAKE - F# Make 231 | .fake/ 232 | -------------------------------------------------------------------------------- /src/Valhalla.Web/BaseController.cs: -------------------------------------------------------------------------------- 1 | using MediatR; 2 | using Microsoft.AspNetCore.Mvc; 3 | using Microsoft.Extensions.DependencyInjection; 4 | 5 | namespace Valhalla.Web 6 | { 7 | [ApiController] 8 | [Route("api/[controller]")] 9 | public abstract class BaseController : Controller 10 | { 11 | private IMediator _mediator; 12 | protected IMediator Mediator 13 | => _mediator ?? 14 | (_mediator = HttpContext.RequestServices.GetService()); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/Valhalla.Web/ClientApp/.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | max_line_length = off 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /src/Valhalla.Web/ClientApp/.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # compiled output 4 | /dist 5 | /dist-server 6 | /tmp 7 | /out-tsc 8 | 9 | # dependencies 10 | /node_modules 11 | 12 | # IDEs and editors 13 | /.idea 14 | .project 15 | .classpath 16 | .c9/ 17 | *.launch 18 | .settings/ 19 | *.sublime-workspace 20 | 21 | # IDE - VSCode 22 | .vscode/* 23 | !.vscode/settings.json 24 | !.vscode/tasks.json 25 | !.vscode/launch.json 26 | !.vscode/extensions.json 27 | 28 | # misc 29 | /.sass-cache 30 | /connect.lock 31 | /coverage 32 | /libpeerconnection.log 33 | npm-debug.log 34 | yarn-error.log 35 | testem.log 36 | /typings 37 | 38 | # System Files 39 | .DS_Store 40 | Thumbs.db 41 | -------------------------------------------------------------------------------- /src/Valhalla.Web/ClientApp/README.md: -------------------------------------------------------------------------------- 1 | # Valhalla.Web 2 | 3 | This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 6.0.0. 4 | 5 | ## Development server 6 | 7 | Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files. 8 | 9 | ## Code scaffolding 10 | 11 | Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`. 12 | 13 | ## Build 14 | 15 | Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `--prod` flag for a production build. 16 | 17 | ## Running unit tests 18 | 19 | Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io). 20 | 21 | ## Running end-to-end tests 22 | 23 | Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/). 24 | 25 | ## Further help 26 | 27 | To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md). 28 | -------------------------------------------------------------------------------- /src/Valhalla.Web/ClientApp/angular.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "./node_modules/@angular/cli/lib/config/schema.json", 3 | "version": 1, 4 | "newProjectRoot": "projects", 5 | "projects": { 6 | "Valhalla.Web": { 7 | "root": "", 8 | "sourceRoot": "src", 9 | "projectType": "application", 10 | "prefix": "app", 11 | "schematics": {}, 12 | "architect": { 13 | "build": { 14 | "builder": "@angular-devkit/build-angular:browser", 15 | "options": { 16 | "progress": false, 17 | "extractCss": true, 18 | "outputPath": "dist", 19 | "index": "src/index.html", 20 | "main": "src/main.ts", 21 | "polyfills": "src/polyfills.ts", 22 | "tsConfig": "src/tsconfig.app.json", 23 | "assets": ["src/assets"], 24 | "styles": [ 25 | "node_modules/bootstrap/dist/css/bootstrap.min.css", 26 | "src/styles.css" 27 | ], 28 | "scripts": [] 29 | }, 30 | "configurations": { 31 | "production": { 32 | "fileReplacements": [ 33 | { 34 | "replace": "src/environments/environment.ts", 35 | "with": "src/environments/environment.prod.ts" 36 | } 37 | ], 38 | "optimization": true, 39 | "outputHashing": "all", 40 | "sourceMap": false, 41 | "extractCss": true, 42 | "namedChunks": false, 43 | "aot": true, 44 | "extractLicenses": true, 45 | "vendorChunk": false, 46 | "buildOptimizer": true 47 | } 48 | } 49 | }, 50 | "serve": { 51 | "builder": "@angular-devkit/build-angular:dev-server", 52 | "options": { 53 | "browserTarget": "Valhalla.Web:build" 54 | }, 55 | "configurations": { 56 | "production": { 57 | "browserTarget": "Valhalla.Web:build:production" 58 | } 59 | } 60 | }, 61 | "extract-i18n": { 62 | "builder": "@angular-devkit/build-angular:extract-i18n", 63 | "options": { 64 | "browserTarget": "Valhalla.Web:build" 65 | } 66 | }, 67 | "test": { 68 | "builder": "@angular-devkit/build-angular:karma", 69 | "options": { 70 | "main": "src/test.ts", 71 | "polyfills": "src/polyfills.ts", 72 | "tsConfig": "src/tsconfig.spec.json", 73 | "karmaConfig": "src/karma.conf.js", 74 | "styles": ["src/styles.css"], 75 | "scripts": [], 76 | "assets": ["src/assets"] 77 | } 78 | }, 79 | "lint": { 80 | "builder": "@angular-devkit/build-angular:tslint", 81 | "options": { 82 | "tsConfig": ["src/tsconfig.app.json", "src/tsconfig.spec.json"], 83 | "exclude": ["**/node_modules/**"] 84 | } 85 | }, 86 | "server": { 87 | "builder": "@angular-devkit/build-angular:server", 88 | "options": { 89 | "outputPath": "dist-server", 90 | "main": "src/main.ts", 91 | "tsConfig": "src/tsconfig.server.json" 92 | }, 93 | "configurations": { 94 | "dev": { 95 | "optimization": true, 96 | "outputHashing": "all", 97 | "sourceMap": false, 98 | "namedChunks": false, 99 | "extractLicenses": true, 100 | "vendorChunk": true 101 | }, 102 | "production": { 103 | "optimization": true, 104 | "outputHashing": "all", 105 | "sourceMap": false, 106 | "namedChunks": false, 107 | "extractLicenses": true, 108 | "vendorChunk": false 109 | } 110 | } 111 | } 112 | } 113 | }, 114 | "Valhalla.Web-e2e": { 115 | "root": "e2e/", 116 | "projectType": "application", 117 | "architect": { 118 | "e2e": { 119 | "builder": "@angular-devkit/build-angular:protractor", 120 | "options": { 121 | "protractorConfig": "e2e/protractor.conf.js", 122 | "devServerTarget": "Valhalla.Web:serve" 123 | } 124 | }, 125 | "lint": { 126 | "builder": "@angular-devkit/build-angular:tslint", 127 | "options": { 128 | "tsConfig": "e2e/tsconfig.e2e.json", 129 | "exclude": ["**/node_modules/**"] 130 | } 131 | } 132 | } 133 | } 134 | }, 135 | "defaultProject": "Valhalla.Web" 136 | } 137 | -------------------------------------------------------------------------------- /src/Valhalla.Web/ClientApp/browserslist: -------------------------------------------------------------------------------- 1 | # This file is currently used by autoprefixer to adjust CSS to support the below specified browsers 2 | # For additional information regarding the format and rule options, please see: 3 | # https://github.com/browserslist/browserslist#queries 4 | # For IE 9-11 support, please uncomment the last line of the file and adjust as needed 5 | > 0.5% 6 | last 2 versions 7 | Firefox ESR 8 | not dead 9 | # IE 9-11 -------------------------------------------------------------------------------- /src/Valhalla.Web/ClientApp/e2e/protractor.conf.js: -------------------------------------------------------------------------------- 1 | // Protractor configuration file, see link for more information 2 | // https://github.com/angular/protractor/blob/master/lib/config.ts 3 | 4 | const { SpecReporter } = require("jasmine-spec-reporter"); 5 | 6 | exports.config = { 7 | allScriptsTimeout: 11000, 8 | specs: ["./src/**/*.e2e-spec.ts"], 9 | capabilities: { 10 | browserName: "chrome" 11 | }, 12 | directConnect: true, 13 | baseUrl: "http://localhost:4200/", 14 | framework: "jasmine", 15 | jasmineNodeOpts: { 16 | showColors: true, 17 | defaultTimeoutInterval: 30000, 18 | print: function() {} 19 | }, 20 | onPrepare() { 21 | require("ts-node").register({ 22 | project: require("path").join(__dirname, "./tsconfig.e2e.json") 23 | }); 24 | jasmine 25 | .getEnv() 26 | .addReporter(new SpecReporter({ spec: { displayStacktrace: true } })); 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /src/Valhalla.Web/ClientApp/e2e/src/app.e2e-spec.ts: -------------------------------------------------------------------------------- 1 | import { AppPage } from './app.po'; 2 | 3 | describe('App', () => { 4 | let page: AppPage; 5 | 6 | beforeEach(() => { 7 | page = new AppPage(); 8 | }); 9 | 10 | it('should display welcome message', () => { 11 | page.navigateTo(); 12 | expect(page.getMainHeading()).toEqual('Hello, world!'); 13 | }); 14 | }); 15 | -------------------------------------------------------------------------------- /src/Valhalla.Web/ClientApp/e2e/src/app.po.ts: -------------------------------------------------------------------------------- 1 | import { browser, by, element } from 'protractor'; 2 | 3 | export class AppPage { 4 | navigateTo() { 5 | return browser.get('/'); 6 | } 7 | 8 | getMainHeading() { 9 | return element(by.css('app-root h1')).getText(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/Valhalla.Web/ClientApp/e2e/tsconfig.e2e.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/app", 5 | "module": "commonjs", 6 | "target": "es5", 7 | "types": [ 8 | "jasmine", 9 | "jasminewd2", 10 | "node" 11 | ] 12 | } 13 | } -------------------------------------------------------------------------------- /src/Valhalla.Web/ClientApp/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "valhalla.web", 3 | "version": "0.0.0", 4 | "scripts": { 5 | "ng": "ng", 6 | "start": "ng serve", 7 | "build": "ng build", 8 | "build:ssr": "ng run Valhalla.Web:server:dev", 9 | "test": "ng test", 10 | "lint": "ng lint", 11 | "e2e": "ng e2e" 12 | }, 13 | "private": true, 14 | "dependencies": { 15 | "@angular/animations": "8.2.12", 16 | "@angular/common": "8.2.12", 17 | "@angular/compiler": "8.2.12", 18 | "@angular/core": "8.2.12", 19 | "@angular/forms": "8.2.12", 20 | "@angular/platform-browser": "8.2.12", 21 | "@angular/platform-browser-dynamic": "8.2.12", 22 | "@angular/platform-server": "8.2.12", 23 | "@angular/router": "8.2.12", 24 | "@nguniversal/module-map-ngfactory-loader": "8.1.1", 25 | "aspnet-prerendering": "^3.0.1", 26 | "bootstrap": "^4.3.1", 27 | "core-js": "^3.3.3", 28 | "jquery": "3.4.1", 29 | "oidc-client": "^1.9.1", 30 | "popper.js": "^1.16.0", 31 | "rxjs": "^6.5.3", 32 | "zone.js": "0.9.1" 33 | }, 34 | "devDependencies": { 35 | "@angular-devkit/build-angular": "^0.803.14", 36 | "@angular/cli": "8.3.14", 37 | "@angular/compiler-cli": "8.2.12", 38 | "@angular/language-service": "8.2.12", 39 | "@types/jasmine": "~3.4.4", 40 | "@types/jasminewd2": "~2.0.8", 41 | "@types/node": "~12.11.6", 42 | "codelyzer": "^5.2.0", 43 | "jasmine-core": "~3.5.0", 44 | "jasmine-spec-reporter": "~4.2.1", 45 | "karma": "^4.4.1", 46 | "karma-chrome-launcher": "~3.1.0", 47 | "karma-coverage-istanbul-reporter": "~2.1.0", 48 | "karma-jasmine": "~2.0.1", 49 | "karma-jasmine-html-reporter": "^1.4.2", 50 | "typescript": "3.5.3" 51 | }, 52 | "optionalDependencies": { 53 | "node-sass": "^4.12.0", 54 | "protractor": "~5.4.2", 55 | "ts-node": "~8.4.1", 56 | "tslint": "~5.20.0" 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/Valhalla.Web/ClientApp/src/app/app.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 |
6 | 7 | -------------------------------------------------------------------------------- /src/Valhalla.Web/ClientApp/src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-root', 5 | templateUrl: './app.component.html' 6 | }) 7 | export class AppComponent { 8 | title = 'app'; 9 | } 10 | -------------------------------------------------------------------------------- /src/Valhalla.Web/ClientApp/src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import { BrowserModule } from '@angular/platform-browser'; 2 | import { NgModule } from '@angular/core'; 3 | import { FormsModule } from '@angular/forms'; 4 | import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http'; 5 | import { RouterModule } from '@angular/router'; 6 | 7 | import { AppComponent } from './app.component'; 8 | import { NavMenuComponent } from './nav-menu/nav-menu.component'; 9 | import { HomeComponent } from './home/home.component'; 10 | import { CounterComponent } from './counter/counter.component'; 11 | import { FetchDataComponent } from './fetch-data/fetch-data.component'; 12 | 13 | @NgModule({ 14 | declarations: [ 15 | AppComponent, 16 | NavMenuComponent, 17 | HomeComponent, 18 | CounterComponent, 19 | FetchDataComponent 20 | ], 21 | imports: [ 22 | BrowserModule.withServerTransition({ appId: 'ng-cli-universal' }), 23 | HttpClientModule, 24 | FormsModule, 25 | RouterModule.forRoot([ 26 | { path: '', component: HomeComponent, pathMatch: 'full' }, 27 | { path: 'counter', component: CounterComponent }, 28 | { path: 'fetch-data', component: FetchDataComponent }, 29 | ]) 30 | ], 31 | providers: [], 32 | bootstrap: [AppComponent] 33 | }) 34 | export class AppModule { } 35 | -------------------------------------------------------------------------------- /src/Valhalla.Web/ClientApp/src/app/app.server.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { ServerModule } from '@angular/platform-server'; 3 | import { ModuleMapLoaderModule } from '@nguniversal/module-map-ngfactory-loader'; 4 | import { AppComponent } from './app.component'; 5 | import { AppModule } from './app.module'; 6 | 7 | @NgModule({ 8 | imports: [AppModule, ServerModule, ModuleMapLoaderModule], 9 | bootstrap: [AppComponent] 10 | }) 11 | export class AppServerModule { } 12 | -------------------------------------------------------------------------------- /src/Valhalla.Web/ClientApp/src/app/counter/counter.component.html: -------------------------------------------------------------------------------- 1 |

Counter

2 | 3 |

This is a simple example of an Angular component.

4 | 5 |

Current count: {{ currentCount }}

6 | 7 | 8 | -------------------------------------------------------------------------------- /src/Valhalla.Web/ClientApp/src/app/counter/counter.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { CounterComponent } from './counter.component'; 4 | 5 | describe('CounterComponent', () => { 6 | let component: CounterComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ CounterComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(CounterComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should display a title', async(() => { 23 | const titleText = fixture.nativeElement.querySelector('h1').textContent; 24 | expect(titleText).toEqual('Counter'); 25 | })); 26 | 27 | it('should start with count 0, then increments by 1 when clicked', async(() => { 28 | const countElement = fixture.nativeElement.querySelector('strong'); 29 | expect(countElement.textContent).toEqual('0'); 30 | 31 | const incrementButton = fixture.nativeElement.querySelector('button'); 32 | incrementButton.click(); 33 | fixture.detectChanges(); 34 | expect(countElement.textContent).toEqual('1'); 35 | })); 36 | }); 37 | -------------------------------------------------------------------------------- /src/Valhalla.Web/ClientApp/src/app/counter/counter.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-counter-component', 5 | templateUrl: './counter.component.html' 6 | }) 7 | export class CounterComponent { 8 | public currentCount = 0; 9 | 10 | public incrementCounter() { 11 | this.currentCount++; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Valhalla.Web/ClientApp/src/app/fetch-data/fetch-data.component.html: -------------------------------------------------------------------------------- 1 |

Weather forecast

2 | 3 |

This component demonstrates fetching data from the server.

4 | 5 |

Loading...

6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 |
DateTemp. (C)Temp. (F)Summary
{{ forecast.date }}{{ forecast.temperatureC }}{{ forecast.temperatureF }}{{ forecast.summary }}
25 | -------------------------------------------------------------------------------- /src/Valhalla.Web/ClientApp/src/app/fetch-data/fetch-data.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Inject } from '@angular/core'; 2 | import { HttpClient } from '@angular/common/http'; 3 | 4 | @Component({ 5 | selector: 'app-fetch-data', 6 | templateUrl: './fetch-data.component.html' 7 | }) 8 | export class FetchDataComponent { 9 | public forecasts: WeatherForecast[]; 10 | 11 | constructor(http: HttpClient, @Inject('BASE_URL') baseUrl: string) { 12 | http.get(baseUrl + 'weatherforecast').subscribe(result => { 13 | this.forecasts = result; 14 | }, error => console.error(error)); 15 | } 16 | } 17 | 18 | interface WeatherForecast { 19 | date: string; 20 | temperatureC: number; 21 | temperatureF: number; 22 | summary: string; 23 | } 24 | -------------------------------------------------------------------------------- /src/Valhalla.Web/ClientApp/src/app/home/home.component.html: -------------------------------------------------------------------------------- 1 |

Hello, world!

2 |

Welcome to your new single-page application, built with:

3 | 8 |

To help you get started, we've also set up:

9 |
    10 |
  • Client-side navigation. For example, click Counter then Back to return here.
  • 11 |
  • Angular CLI integration. In development mode, there's no need to run ng serve. It runs in the background automatically, so your client-side resources are dynamically built on demand and the page refreshes when you modify any file.
  • 12 |
  • Efficient production builds. In production mode, development-time features are disabled, and your dotnet publish configuration automatically invokes ng build to produce minified, ahead-of-time compiled JavaScript files.
  • 13 |
14 |

The ClientApp subdirectory is a standard Angular CLI application. If you open a command prompt in that directory, you can run any ng command (e.g., ng test), or use npm to install extra packages into it.

15 | -------------------------------------------------------------------------------- /src/Valhalla.Web/ClientApp/src/app/home/home.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-home', 5 | templateUrl: './home.component.html', 6 | }) 7 | export class HomeComponent { 8 | } 9 | -------------------------------------------------------------------------------- /src/Valhalla.Web/ClientApp/src/app/nav-menu/nav-menu.component.css: -------------------------------------------------------------------------------- 1 | a.navbar-brand { 2 | white-space: normal; 3 | text-align: center; 4 | word-break: break-all; 5 | } 6 | 7 | html { 8 | font-size: 14px; 9 | } 10 | @media (min-width: 768px) { 11 | html { 12 | font-size: 16px; 13 | } 14 | } 15 | 16 | .box-shadow { 17 | box-shadow: 0 .25rem .75rem rgba(0, 0, 0, .05); 18 | } 19 | -------------------------------------------------------------------------------- /src/Valhalla.Web/ClientApp/src/app/nav-menu/nav-menu.component.html: -------------------------------------------------------------------------------- 1 |
2 | 44 |
45 | -------------------------------------------------------------------------------- /src/Valhalla.Web/ClientApp/src/app/nav-menu/nav-menu.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-nav-menu', 5 | templateUrl: './nav-menu.component.html', 6 | styleUrls: ['./nav-menu.component.css'] 7 | }) 8 | export class NavMenuComponent { 9 | isExpanded = false; 10 | 11 | collapse() { 12 | this.isExpanded = false; 13 | } 14 | 15 | toggle() { 16 | this.isExpanded = !this.isExpanded; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Valhalla.Web/ClientApp/src/assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rcarneironet/valhalla-clean-architecture/bb54d24807e9605c1bbdc642ac0d53bcf37b0ac9/src/Valhalla.Web/ClientApp/src/assets/.gitkeep -------------------------------------------------------------------------------- /src/Valhalla.Web/ClientApp/src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true 3 | }; 4 | -------------------------------------------------------------------------------- /src/Valhalla.Web/ClientApp/src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | // This file can be replaced during build by using the `fileReplacements` array. 2 | // `ng build ---prod` replaces `environment.ts` with `environment.prod.ts`. 3 | // The list of file replacements can be found in `angular.json`. 4 | 5 | export const environment = { 6 | production: false 7 | }; 8 | 9 | /* 10 | * In development mode, to ignore zone related error stack frames such as 11 | * `zone.run`, `zoneDelegate.invokeTask` for easier debugging, you can 12 | * import the following file, but please comment it out in production mode 13 | * because it will have performance impact when throw error 14 | */ 15 | // import 'zone.js/dist/zone-error'; // Included with Angular CLI. 16 | -------------------------------------------------------------------------------- /src/Valhalla.Web/ClientApp/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Valhalla.Web 6 | 7 | 8 | 9 | 10 | 11 | 12 | Loading... 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/Valhalla.Web/ClientApp/src/karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration file, see link for more information 2 | // https://karma-runner.github.io/1.0/config/configuration-file.html 3 | 4 | module.exports = function (config) { 5 | config.set({ 6 | basePath: '', 7 | frameworks: ['jasmine', '@angular-devkit/build-angular'], 8 | plugins: [ 9 | require('karma-jasmine'), 10 | require('karma-chrome-launcher'), 11 | require('karma-jasmine-html-reporter'), 12 | require('karma-coverage-istanbul-reporter'), 13 | require('@angular-devkit/build-angular/plugins/karma') 14 | ], 15 | client: { 16 | clearContext: false // leave Jasmine Spec Runner output visible in browser 17 | }, 18 | coverageIstanbulReporter: { 19 | dir: require('path').join(__dirname, '../coverage'), 20 | reports: ['html', 'lcovonly'], 21 | fixWebpackSourcePaths: true 22 | }, 23 | reporters: ['progress', 'kjhtml'], 24 | port: 9876, 25 | colors: true, 26 | logLevel: config.LOG_INFO, 27 | autoWatch: true, 28 | browsers: ['Chrome'], 29 | singleRun: false 30 | }); 31 | }; 32 | -------------------------------------------------------------------------------- /src/Valhalla.Web/ClientApp/src/main.ts: -------------------------------------------------------------------------------- 1 | import { enableProdMode } from '@angular/core'; 2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 3 | 4 | import { AppModule } from './app/app.module'; 5 | import { environment } from './environments/environment'; 6 | 7 | export function getBaseUrl() { 8 | return document.getElementsByTagName('base')[0].href; 9 | } 10 | 11 | const providers = [ 12 | { provide: 'BASE_URL', useFactory: getBaseUrl, deps: [] } 13 | ]; 14 | 15 | if (environment.production) { 16 | enableProdMode(); 17 | } 18 | 19 | platformBrowserDynamic(providers).bootstrapModule(AppModule) 20 | .catch(err => console.log(err)); 21 | -------------------------------------------------------------------------------- /src/Valhalla.Web/ClientApp/src/polyfills.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file includes polyfills needed by Angular and is loaded before the app. 3 | * You can add your own extra polyfills to this file. 4 | * 5 | * This file is divided into 2 sections: 6 | * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. 7 | * 2. Application imports. Files imported after ZoneJS that should be loaded before your main 8 | * file. 9 | * 10 | * The current setup is for so-called "evergreen" browsers; the last versions of browsers that 11 | * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera), 12 | * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile. 13 | * 14 | * Learn more in https://angular.io/guide/browser-support 15 | */ 16 | 17 | /*************************************************************************************************** 18 | * BROWSER POLYFILLS 19 | */ 20 | 21 | /** IE10 and IE11 requires the following for NgClass support on SVG elements */ 22 | // import 'classlist.js'; // Run `npm install --save classlist.js`. 23 | 24 | /** 25 | * Web Animations `@angular/platform-browser/animations` 26 | * Only required if AnimationBuilder is used within the application and using IE/Edge or Safari. 27 | * Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0). 28 | */ 29 | // import 'web-animations-js'; // Run `npm install --save web-animations-js`. 30 | 31 | /** 32 | * By default, zone.js will patch all possible macroTask and DomEvents 33 | * user can disable parts of macroTask/DomEvents patch by setting following flags 34 | * because those flags need to be set before `zone.js` being loaded, and webpack 35 | * will put import in the top of bundle, so user need to create a separate file 36 | * in this directory (for example: zone-flags.ts), and put the following flags 37 | * into that file, and then add the following code before importing zone.js. 38 | * import './zone-flags.ts'; 39 | * 40 | * The flags allowed in zone-flags.ts are listed here. 41 | * 42 | * The following flags will work for all browsers. 43 | * 44 | * (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame 45 | * (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick 46 | * (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames 47 | * 48 | * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js 49 | * with the following flag, it will bypass `zone.js` patch for IE/Edge 50 | * 51 | * (window as any).__Zone_enable_cross_context_check = true; 52 | * 53 | */ 54 | 55 | /*************************************************************************************************** 56 | * Zone JS is required by default for Angular itself. 57 | */ 58 | import 'zone.js/dist/zone'; // Included with Angular CLI. 59 | 60 | 61 | /*************************************************************************************************** 62 | * APPLICATION IMPORTS 63 | */ 64 | -------------------------------------------------------------------------------- /src/Valhalla.Web/ClientApp/src/styles.css: -------------------------------------------------------------------------------- 1 | /* You can add global styles to this file, and also import other style files */ 2 | 3 | /* Provide sufficient contrast against white background */ 4 | a { 5 | color: #0366d6; 6 | } 7 | 8 | code { 9 | color: #e01a76; 10 | } 11 | 12 | .btn-primary { 13 | color: #fff; 14 | background-color: #1b6ec2; 15 | border-color: #1861ac; 16 | } 17 | -------------------------------------------------------------------------------- /src/Valhalla.Web/ClientApp/src/test.ts: -------------------------------------------------------------------------------- 1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files 2 | 3 | import 'zone.js/dist/zone-testing'; 4 | import { getTestBed } from '@angular/core/testing'; 5 | import { 6 | BrowserDynamicTestingModule, 7 | platformBrowserDynamicTesting 8 | } from '@angular/platform-browser-dynamic/testing'; 9 | 10 | declare const require: any; 11 | 12 | // First, initialize the Angular testing environment. 13 | getTestBed().initTestEnvironment( 14 | BrowserDynamicTestingModule, 15 | platformBrowserDynamicTesting() 16 | ); 17 | // Then we find all the tests. 18 | const context = require.context('./', true, /\.spec\.ts$/); 19 | // And load the modules. 20 | context.keys().map(context); 21 | -------------------------------------------------------------------------------- /src/Valhalla.Web/ClientApp/src/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/app", 5 | "types": [] 6 | }, 7 | "exclude": [ 8 | "src/test.ts", 9 | "**/*.spec.ts" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /src/Valhalla.Web/ClientApp/src/tsconfig.server.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "module": "commonjs" 5 | }, 6 | "angularCompilerOptions": { 7 | "entryModule": "app/app.server.module#AppServerModule" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/Valhalla.Web/ClientApp/src/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/spec", 5 | "types": [ 6 | "jasmine", 7 | "node" 8 | ] 9 | }, 10 | "files": [ 11 | "test.ts", 12 | "polyfills.ts" 13 | ], 14 | "include": [ 15 | "**/*.spec.ts", 16 | "**/*.d.ts" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /src/Valhalla.Web/ClientApp/src/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tslint.json", 3 | "rules": { 4 | "directive-selector": [ 5 | true, 6 | "attribute", 7 | "app", 8 | "camelCase" 9 | ], 10 | "component-selector": [ 11 | true, 12 | "element", 13 | "app", 14 | "kebab-case" 15 | ] 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/Valhalla.Web/ClientApp/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": false, 3 | "compilerOptions": { 4 | "baseUrl": "./", 5 | "module": "esnext", 6 | "outDir": "./dist/out-tsc", 7 | "sourceMap": true, 8 | "declaration": false, 9 | "moduleResolution": "node", 10 | "emitDecoratorMetadata": true, 11 | "experimentalDecorators": true, 12 | "target": "es2015", 13 | "typeRoots": [ 14 | "node_modules/@types" 15 | ], 16 | "lib": [ 17 | "es2017", 18 | "dom" 19 | ] 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Valhalla.Web/ClientApp/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "rulesDirectory": [ 3 | "node_modules/codelyzer" 4 | ], 5 | "rules": { 6 | "arrow-return-shorthand": true, 7 | "callable-types": true, 8 | "class-name": true, 9 | "comment-format": [ 10 | true, 11 | "check-space" 12 | ], 13 | "curly": true, 14 | "deprecation": { 15 | "severity": "warn" 16 | }, 17 | "eofline": true, 18 | "forin": true, 19 | "import-blacklist": [ 20 | true, 21 | "rxjs/Rx" 22 | ], 23 | "import-spacing": true, 24 | "indent": [ 25 | true, 26 | "spaces" 27 | ], 28 | "interface-over-type-literal": true, 29 | "label-position": true, 30 | "max-line-length": [ 31 | true, 32 | 140 33 | ], 34 | "member-access": false, 35 | "member-ordering": [ 36 | true, 37 | { 38 | "order": [ 39 | "static-field", 40 | "instance-field", 41 | "static-method", 42 | "instance-method" 43 | ] 44 | } 45 | ], 46 | "no-arg": true, 47 | "no-bitwise": true, 48 | "no-console": [ 49 | true, 50 | "debug", 51 | "info", 52 | "time", 53 | "timeEnd", 54 | "trace" 55 | ], 56 | "no-construct": true, 57 | "no-debugger": true, 58 | "no-duplicate-super": true, 59 | "no-empty": false, 60 | "no-empty-interface": true, 61 | "no-eval": true, 62 | "no-inferrable-types": [ 63 | true, 64 | "ignore-params" 65 | ], 66 | "no-misused-new": true, 67 | "no-non-null-assertion": true, 68 | "no-shadowed-variable": true, 69 | "no-string-literal": false, 70 | "no-string-throw": true, 71 | "no-switch-case-fall-through": true, 72 | "no-trailing-whitespace": true, 73 | "no-unnecessary-initializer": true, 74 | "no-unused-expression": true, 75 | "no-use-before-declare": true, 76 | "no-var-keyword": true, 77 | "object-literal-sort-keys": false, 78 | "one-line": [ 79 | true, 80 | "check-open-brace", 81 | "check-catch", 82 | "check-else", 83 | "check-whitespace" 84 | ], 85 | "prefer-const": true, 86 | "quotemark": [ 87 | true, 88 | "single" 89 | ], 90 | "radix": true, 91 | "semicolon": [ 92 | true, 93 | "always" 94 | ], 95 | "triple-equals": [ 96 | true, 97 | "allow-null-check" 98 | ], 99 | "typedef-whitespace": [ 100 | true, 101 | { 102 | "call-signature": "nospace", 103 | "index-signature": "nospace", 104 | "parameter": "nospace", 105 | "property-declaration": "nospace", 106 | "variable-declaration": "nospace" 107 | } 108 | ], 109 | "unified-signatures": true, 110 | "variable-name": false, 111 | "whitespace": [ 112 | true, 113 | "check-branch", 114 | "check-decl", 115 | "check-operator", 116 | "check-separator", 117 | "check-type" 118 | ], 119 | "no-output-on-prefix": true, 120 | "no-inputs-metadata-property": true, 121 | "no-outputs-metadata-property": true, 122 | "no-host-metadata-property": true, 123 | "no-input-rename": true, 124 | "no-output-rename": true, 125 | "use-lifecycle-interface": true, 126 | "use-pipe-transform-interface": true, 127 | "component-class-suffix": true, 128 | "directive-class-suffix": true 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /src/Valhalla.Web/Controllers/UseCases/Courses/InitializeController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Http; 2 | using Microsoft.AspNetCore.Mvc; 3 | using System.Threading.Tasks; 4 | using Valhalla.Application.UseCases.Courses.Queries.ViewAllCourses; 5 | 6 | namespace Valhalla.Web.Controllers.UseCases.Courses 7 | { 8 | public class InitializeController : BaseController 9 | { 10 | 11 | [HttpGet("EfCore")] 12 | [ProducesResponseType(StatusCodes.Status200OK)] 13 | [ProducesResponseType(StatusCodes.Status404NotFound)] 14 | [ProducesResponseType(StatusCodes.Status500InternalServerError)] 15 | public async Task> InitializeEfCore() 16 | { 17 | return Ok(await Mediator.Send(new ViewAllCoursesQuery())); 18 | } 19 | 20 | [HttpGet("Dapper")] 21 | [ProducesResponseType(StatusCodes.Status200OK)] 22 | [ProducesResponseType(StatusCodes.Status404NotFound)] 23 | [ProducesResponseType(StatusCodes.Status500InternalServerError)] 24 | public async Task> InitializeDapper() 25 | { 26 | return Ok(await Mediator.Send(new ViewAllCoursesDapperQuery())); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Valhalla.Web/Pages/Error.cshtml: -------------------------------------------------------------------------------- 1 | @page 2 | @model ErrorModel 3 | @{ 4 | ViewData["Title"] = "Error"; 5 | } 6 | 7 |

Error.

8 |

An error occurred while processing your request.

9 | 10 | @if (Model.ShowRequestId) 11 | { 12 |

13 | Request ID: @Model.RequestId 14 |

15 | } 16 | 17 |

Development Mode

18 |

19 | Swapping to the Development environment displays detailed information about the error that occurred. 20 |

21 |

22 | The Development environment shouldn't be enabled for deployed applications. 23 | It can result in displaying sensitive information from exceptions to end users. 24 | For local debugging, enable the Development environment by setting the ASPNETCORE_ENVIRONMENT environment variable to Development 25 | and restarting the app. 26 |

27 | -------------------------------------------------------------------------------- /src/Valhalla.Web/Pages/Error.cshtml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using Microsoft.AspNetCore.Mvc; 7 | using Microsoft.AspNetCore.Mvc.RazorPages; 8 | using Microsoft.Extensions.Logging; 9 | 10 | namespace Valhalla.Web.Pages 11 | { 12 | [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] 13 | public class ErrorModel : PageModel 14 | { 15 | private readonly ILogger _logger; 16 | 17 | public ErrorModel(ILogger logger) 18 | { 19 | _logger = logger; 20 | } 21 | 22 | public string RequestId { get; set; } 23 | 24 | public bool ShowRequestId => !string.IsNullOrEmpty(RequestId); 25 | 26 | public void OnGet() 27 | { 28 | RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Valhalla.Web/Pages/_ViewImports.cshtml: -------------------------------------------------------------------------------- 1 | @using Valhalla.Web 2 | @namespace Valhalla.Web.Pages 3 | @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers 4 | -------------------------------------------------------------------------------- /src/Valhalla.Web/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Hosting; 6 | using Microsoft.Extensions.Configuration; 7 | using Microsoft.Extensions.Hosting; 8 | using Microsoft.Extensions.Logging; 9 | 10 | namespace Valhalla.Web 11 | { 12 | public class Program 13 | { 14 | public static void Main(string[] args) 15 | { 16 | CreateHostBuilder(args).Build().Run(); 17 | } 18 | 19 | public static IHostBuilder CreateHostBuilder(string[] args) => 20 | Host.CreateDefaultBuilder(args) 21 | .ConfigureWebHostDefaults(webBuilder => 22 | { 23 | webBuilder.UseStartup(); 24 | }); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Valhalla.Web/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:55602", 7 | "sslPort": 44372 8 | } 9 | }, 10 | "profiles": { 11 | "IIS Express": { 12 | "commandName": "IISExpress", 13 | "launchBrowser": true, 14 | "environmentVariables": { 15 | "ASPNETCORE_ENVIRONMENT": "Development" 16 | } 17 | }, 18 | "Valhalla.Web": { 19 | "commandName": "Project", 20 | "environmentVariables": { 21 | "ASPNETCORE_ENVIRONMENT": "Development" 22 | }, 23 | "applicationUrl": "https://localhost:5001;http://localhost:5000" 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /src/Valhalla.Web/Startup.cs: -------------------------------------------------------------------------------- 1 | using AutoMapper; 2 | using MediatR; 3 | using Microsoft.AspNetCore.Builder; 4 | using Microsoft.AspNetCore.Hosting; 5 | using Microsoft.AspNetCore.SpaServices.AngularCli; 6 | using Microsoft.EntityFrameworkCore; 7 | using Microsoft.Extensions.Configuration; 8 | using Microsoft.Extensions.DependencyInjection; 9 | using Microsoft.Extensions.Hosting; 10 | using System.Reflection; 11 | using Valhalla.Application.Abstractions.EntityFramework; 12 | using Valhalla.Application.UseCases.Courses.Queries.ViewAllCourses; 13 | using Valhalla.Infrastructure.AutoMapper; 14 | using Valhalla.Infrastructure.DataAccess.EntityFramework; 15 | using Valhalla.Infrastructure.IoC; 16 | 17 | namespace Valhalla.Web 18 | { 19 | public class Startup 20 | { 21 | public Startup(IConfiguration configuration) 22 | { 23 | Configuration = configuration; 24 | } 25 | 26 | public IConfiguration Configuration { get; } 27 | 28 | public void ConfigureServices(IServiceCollection services) 29 | { 30 | //Register Services 31 | services.RegisterRepositoryServices(); 32 | 33 | //Register AutoMapper 34 | services.AddAutoMapper(new Assembly[] { typeof(AutoMapperProfile).GetTypeInfo().Assembly }); 35 | 36 | //CQRS - Queries 37 | services.AddMediatR(typeof(ViewAllCoursesQueryHandler).GetTypeInfo().Assembly); 38 | services.AddMediatR(typeof(ViewAllCoursesDapperQueryHandler).GetTypeInfo().Assembly); 39 | 40 | services.AddDbContext(options => 41 | options.UseSqlServer(Configuration.GetConnectionString("DbConnection"))); 42 | 43 | services.AddControllersWithViews(); 44 | services.AddSpaStaticFiles(configuration => 45 | { 46 | configuration.RootPath = "ClientApp/dist"; 47 | }); 48 | } 49 | 50 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 51 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env) 52 | { 53 | if (env.IsDevelopment()) 54 | { 55 | app.UseDeveloperExceptionPage(); 56 | } 57 | else 58 | { 59 | app.UseExceptionHandler("/Error"); 60 | // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. 61 | app.UseHsts(); 62 | } 63 | 64 | app.UseHttpsRedirection(); 65 | app.UseStaticFiles(); 66 | if (!env.IsDevelopment()) 67 | { 68 | app.UseSpaStaticFiles(); 69 | } 70 | 71 | app.UseRouting(); 72 | 73 | app.UseEndpoints(endpoints => 74 | { 75 | endpoints.MapControllerRoute( 76 | name: "default", 77 | pattern: "{controller}/{action=Index}/{id?}"); 78 | }); 79 | 80 | app.UseCors(c => 81 | { 82 | c.AllowAnyHeader(); 83 | c.AllowAnyMethod(); 84 | c.AllowAnyOrigin(); 85 | }); 86 | 87 | app.UseSpa(spa => 88 | { 89 | // To learn more about options for serving an Angular SPA from ASP.NET Core, 90 | // see https://go.microsoft.com/fwlink/?linkid=864501 91 | 92 | spa.Options.SourcePath = "ClientApp"; 93 | 94 | if (env.IsDevelopment()) 95 | { 96 | spa.UseAngularCliServer(npmScript: "start"); 97 | } 98 | }); 99 | } 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /src/Valhalla.Web/Valhalla.Web.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp3.1 5 | true 6 | Latest 7 | false 8 | ClientApp\ 9 | $(DefaultItemExcludes);$(SpaRoot)node_modules\** 10 | 11 | 12 | false 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | %(DistFiles.Identity) 59 | PreserveNewest 60 | true 61 | 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /src/Valhalla.Web/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/Valhalla.Web/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "ConnectionStrings": { 3 | "DbConnection": "Data Source=OFFICEWS;Initial Catalog=ValhallaDatabase;Integrated Security=True" 4 | }, 5 | "Logging": { 6 | "LogLevel": { 7 | "Default": "Warning" 8 | } 9 | }, 10 | "AllowedHosts": "*" 11 | } 12 | -------------------------------------------------------------------------------- /src/Valhalla.Web/wwwroot/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rcarneironet/valhalla-clean-architecture/bb54d24807e9605c1bbdc642ac0d53bcf37b0ac9/src/Valhalla.Web/wwwroot/favicon.ico -------------------------------------------------------------------------------- /valhalla-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rcarneironet/valhalla-clean-architecture/bb54d24807e9605c1bbdc642ac0d53bcf37b0ac9/valhalla-logo.png -------------------------------------------------------------------------------- /valhalla.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.29613.14 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Valhalla.Application", "src\Valhalla.Application\Valhalla.Application.csproj", "{5841AECD-1010-4C94-8F24-60C1A3117568}" 7 | EndProject 8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Valhalla.Domain", "src\Valhalla.Domain\Valhalla.Domain.csproj", "{3D88D1F1-8149-44F1-93DE-2995F72E2A9C}" 9 | EndProject 10 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Valhalla.Infrastructure", "src\Valhalla.Infrastructure\Valhalla.Infrastructure.csproj", "{299FFB95-6DBC-48F6-B39F-ADC328D862D4}" 11 | EndProject 12 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Presentation", "Presentation", "{A1044771-D897-4C65-915D-7DE254304996}" 13 | EndProject 14 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Valhalla.Web", "src\Valhalla.Web\Valhalla.Web.csproj", "{6CA19093-42CA-4A51-BD90-3EDA8D228384}" 15 | EndProject 16 | Global 17 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 18 | Debug|Any CPU = Debug|Any CPU 19 | Release|Any CPU = Release|Any CPU 20 | EndGlobalSection 21 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 22 | {5841AECD-1010-4C94-8F24-60C1A3117568}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 23 | {5841AECD-1010-4C94-8F24-60C1A3117568}.Debug|Any CPU.Build.0 = Debug|Any CPU 24 | {5841AECD-1010-4C94-8F24-60C1A3117568}.Release|Any CPU.ActiveCfg = Release|Any CPU 25 | {5841AECD-1010-4C94-8F24-60C1A3117568}.Release|Any CPU.Build.0 = Release|Any CPU 26 | {3D88D1F1-8149-44F1-93DE-2995F72E2A9C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 27 | {3D88D1F1-8149-44F1-93DE-2995F72E2A9C}.Debug|Any CPU.Build.0 = Debug|Any CPU 28 | {3D88D1F1-8149-44F1-93DE-2995F72E2A9C}.Release|Any CPU.ActiveCfg = Release|Any CPU 29 | {3D88D1F1-8149-44F1-93DE-2995F72E2A9C}.Release|Any CPU.Build.0 = Release|Any CPU 30 | {299FFB95-6DBC-48F6-B39F-ADC328D862D4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 31 | {299FFB95-6DBC-48F6-B39F-ADC328D862D4}.Debug|Any CPU.Build.0 = Debug|Any CPU 32 | {299FFB95-6DBC-48F6-B39F-ADC328D862D4}.Release|Any CPU.ActiveCfg = Release|Any CPU 33 | {299FFB95-6DBC-48F6-B39F-ADC328D862D4}.Release|Any CPU.Build.0 = Release|Any CPU 34 | {6CA19093-42CA-4A51-BD90-3EDA8D228384}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 35 | {6CA19093-42CA-4A51-BD90-3EDA8D228384}.Debug|Any CPU.Build.0 = Debug|Any CPU 36 | {6CA19093-42CA-4A51-BD90-3EDA8D228384}.Release|Any CPU.ActiveCfg = Release|Any CPU 37 | {6CA19093-42CA-4A51-BD90-3EDA8D228384}.Release|Any CPU.Build.0 = Release|Any CPU 38 | EndGlobalSection 39 | GlobalSection(SolutionProperties) = preSolution 40 | HideSolutionNode = FALSE 41 | EndGlobalSection 42 | GlobalSection(NestedProjects) = preSolution 43 | {6CA19093-42CA-4A51-BD90-3EDA8D228384} = {A1044771-D897-4C65-915D-7DE254304996} 44 | EndGlobalSection 45 | GlobalSection(ExtensibilityGlobals) = postSolution 46 | SolutionGuid = {A23530E5-ECDF-404B-A0CC-734AAC7FE798} 47 | EndGlobalSection 48 | EndGlobal 49 | --------------------------------------------------------------------------------