Transcription of Clean Architecture with ASP.NET Core
1 Clean Architecturewith CoreS T E V E S M I T HA R D A L I S .C O M | @A R D A L I S| S T E V E @ D E V I Q .C O MD E V I Q .C O MLearn More After Today1) Pluralsight N-Tier Apps with C# Domain-Driven Design ) DevIQ Core Quick ) Microsoft FREE eBook/SampleApp ) Contact me for mentoring/training for your company/teamQuestionsHOPEFULLY YOU LL KNOW THE ANSWERS WHEN WE RE DONEWhy do we separateapplications into multiple projects?What are some principleswe can apply when organizingour software modules?How does the organizationof our application s solutionimpact coupling?What problemsresult from certain common approaches?How does Clean Architecture address these problems?Oh yeah, and isn t Core pretty cool? :)PrinciplesA B I T O F G U I D A N C ESeparation of ConcernsAvoid mixing different code responsibilities in the same (method | class | project)The Big Three Data Access Business Rules and Domain Model User InterfaceSingle ResponsibilityWorks in tandem with Separation of ConcernsClasses should focus on a single responsibility a single reason to Don t Repeat Refactor repetitive codeinto functions Group functions into cohesive classes Group classes into folders and namespacesby Responsibility Level of abstraction Etc.
2 Further group class folders into projectsInvert (and inject) Dependencies Both high level classes and implementation-detail classes should depend on abstractions (interfaces). Classes should follow Explicit Dependencies Principle: Request alldependencies via their Abstractions/interfaces must be defined somewhere accessible by: Low level implementation services High level business services User interface entry pointsMake the right thing easy and the wrong thing classes shouldn t depend directly on infrastructure classes How can we structure our solution to help enforce this?Business/domain classes shouldn t depend directly on infrastructure classes How can our solution design help?Repetition of (query logic, validation logic, policies, error handling, anything) is a problem What patternscan we apply to make avoiding repetition easier than copy/pasting? Classic N-Tier ArchitectureO R N-L AY E RSource: MSDN Website, 2001N-Tier BenefitsCode ReuseTeam SegmentationBetter Maintainability(slightly) Looser CouplingN-Tier DrawbacksTransitive Dependencies(some)Complexity(still)Tight CouplingTransitive DependenciesDBData Access LayerBusiness Logic LayerUser Interface LayerEverythingDepends on the databaseDomain-Centric DesignA N D T H E C L E A N A R C H I T E C T U R EDomain ModelNot just business logic A modelof the problem space composed of Entities, Interfaces, Services, and contracts for working with domain objectsEverything in the application (including infrastructure and data access) depends on these interfaces and domain objectsClean ArchitectureOnion ArchitectureHexagonal ArchitecturePorts and AdaptersClean Architecture Rules The Application Corecontains the Domain ModelAll projects depend on the Core project.
3 Dependencies point inwardtoward this coreInner projects define interfaces; outer projects implement themAvoiddirect dependency on Infrastructure project (except from Integration tests) Clean Architecture FeaturesFramework Independent. You can use this Architecture with (Core), Java, Python, etc. It doesn t rely on any software library or proprietary Independent The vast majority of the code has no knowledge of what database, if any, might be used by the application. Often, this knowledge will exist in a single class, in a single project that no other project Independent Only the UI project cares about the UI. The rest of the system is Apps built using this approach, and especially the core domain model and its business rules, are extremely to a Clean ArchitectureBestto start from a properly organized solution See : Start from a single projectMost difficult: Large, existing investment in multi-layer Architecture without abstractions or DIThe CoreProjectMinimal dependencies none on Goes in Core:InterfacesEntitiesValue ObjectsAggregatesDomain ServicesDomain EventsExceptionsSpecificationsEvent HandlersThe InfrastructureProjectAll dependencies on out-of-process Goes in Infrastructure:RepositoriesEF (Core)DbContextWeb API ClientsFile SystemAccessorsEmail/SMS SendingLoggingAdaptersSystem ClockOtherServicesCachedRepositoriesInte rfacesThe WebProjectAll dependencies on out-of-process Goes in Web.
4 ControllersViewsViewModelsFiltersBinders Other ServicesRazorPagesApiModelsBindingModels Tag/Html HelpersOrInterfacesSharing Between Solutions: Shared KernelCommon Types May Be Shared Between Solutions. Will be referenced by Coreproject(s).Ideally distributed as Nuget Goes in Shared Kernel:Base EntityBase Domain EventBase SpecificationCommonExceptionsCommonInter facesCommon User classCommon DICommon LoggingCommon Guard ClausesGuard Clauses?Simple checks for input that use common rules and Package: ( )Example:public void ProcessOrder(Order order){ (order, nameof(order));// process order here}Solution Structure Clean ArchitectureWebCoreInfrastructureShared KernelUnit TestsFunctionalTestsIntegrationTestsTypi cal (Basic) Folder StructureWhat belongs in actions/handlers?Controller Actions or Page Handlers should:1) Accept task-specific types (ViewModel, ApiModel, BindingModel)2) Perform and handle model validation (ideally w/filters)3) Do Work (More on this in a moment)4) Create any model type required for response (ViewModel, ApiModel, etc.
5 5) Return an appropriate Result type (View, Page, Ok, NotFound, etc.) Do Work Option OneRepositories and Entities1) Get entity from an injected Repository2) Work with the entity and its ) Update the entity s state using the RepositoryGreat for simple operationsGreat for CRUD workRequires mappingbetween web models and domain model within controller. Do Work Option TwoWork with an application service. 1) Pass ApiModeltypes to service2) Service internally works with repositories and domain model ) Service returns a web model typeBetter for more complex operationsApplication Service is responsible for mapping between web models and domain controllers lightweight, and with fewer injected dependencies. Do Work Option ThreeWork with commandsand a tool like ) Use ApiModeltypes that represent commands ( RegisterUser)2) Send model-bound instance of command to handler using ()No need to inject separate services to different controllers Mediatrbecomes only WalkthroughResourcesOnline Courses (Pluralsightand DevIQ) SOLID Principles of OO N-Tier Architecture in C# DDD Core Quick OFF!
6 Weekly Dev Tips Microsoft Architecture eBook/