├── MAUI.CleanArchitecture ├── Configuration │ ├── appsettings.debug.json │ └── appsettings.release.json ├── Resources │ ├── Images │ │ ├── login.png │ │ ├── signup.png │ │ ├── add_to_cart.png │ │ ├── signup.svg │ │ └── dotnet_bot.svg │ ├── Fonts │ │ └── OpenSans-Regular.ttf │ ├── appicon.svg │ ├── Raw │ │ └── AboutAssets.txt │ ├── appiconfg.svg │ └── Splash │ │ └── splash.svg ├── Properties │ └── launchSettings.json ├── AppShell.xaml.cs ├── Platforms │ ├── Android │ │ ├── Resources │ │ │ └── values │ │ │ │ └── colors.xml │ │ ├── AndroidManifest.xml │ │ ├── MainApplication.cs │ │ └── MainActivity.cs │ ├── MacCatalyst │ │ ├── AppDelegate.cs │ │ ├── Program.cs │ │ └── Info.plist │ ├── Windows │ │ ├── App.xaml │ │ ├── app.manifest │ │ ├── App.xaml.cs │ │ └── Package.appxmanifest │ └── iOS │ │ ├── Program.cs │ │ ├── AppDelegate.cs │ │ ├── Info.plist │ │ └── Resources │ │ └── LaunchScreen.xib ├── Utils │ ├── IPageManager.cs │ └── PageManager.cs ├── Controls │ ├── CustomStepper.cs │ ├── Errors.xaml │ └── Errors.xaml.cs ├── AppShell.xaml ├── Views │ ├── ContentViews │ │ ├── CardItemView.xaml.cs │ │ └── CardItemView.xaml │ └── Pages │ │ ├── RegisterPageView.xaml.cs │ │ ├── MainPageView.xaml.cs │ │ ├── LoginPageView.xaml.cs │ │ ├── UserInfoPageView.xaml.cs │ │ ├── UserInfoPageView.xaml │ │ ├── LoginPageView.xaml │ │ ├── RegisterPageView.xaml │ │ └── MainPageView.xaml ├── Converters │ ├── DoubleToStringConverter.cs │ └── ImageSourceConverter.cs ├── App.xaml.cs ├── ViewModels │ ├── Base │ │ ├── ViewModelBase.cs │ │ └── ViewModelLocator.cs │ ├── UserInfoPageViewModel.cs │ ├── CardItemViewModel.cs │ ├── LoginPageViewModel.cs │ ├── RegisterPageViewModel.cs │ └── MainPageViewModel.cs ├── App.xaml ├── MauiProgram.cs └── MAUI.CleanArchitecture.csproj ├── MAUI.CleanArchitecture.Domain ├── MainModel.cs ├── MAUI.CleanArchitecture.Domain.csproj ├── Entities │ ├── Rating.cs │ ├── User.cs │ ├── CardItem.cs │ └── StoreItem.cs ├── User │ └── LoginResponseModel.cs └── SubItem.cs ├── MAUI.CleanArchitecture.Infrastructure ├── Persistence │ ├── Constants.cs │ ├── Configurations │ │ ├── RatingConfiguration.cs │ │ ├── CartItemConfiguration.cs │ │ └── StoreItemConfiguration.cs │ ├── StoreDbContext.cs │ └── Migrations │ │ ├── 20211214054413_InitialCreate.cs │ │ ├── StoreDbContextModelSnapshot.cs │ │ └── 20211214054413_InitialCreate.Designer.cs ├── Identity │ └── ApplicationUser.cs ├── BackgroundServices │ └── DbBackgroundService.cs ├── Services │ ├── FakeStoreApiService.cs │ └── AuthenticationService.cs ├── MAUI.CleanArchitecture.Infrastructure.csproj └── DependencyInjection.cs ├── MAUI.CleanArchitecture.Application ├── Store │ └── Queries │ │ └── GetStoreItemsQuery │ │ ├── GetStoreItemsQuery.cs │ │ └── GetStoreItemsQueryHandler.cs ├── Common │ ├── Interfaces │ │ ├── IFakeStoreApiService.cs │ │ ├── IAuthentication.cs │ │ └── IStoreDbContext.cs │ ├── Notificications │ │ ├── AddCardItemNotification.cs │ │ ├── SigninNotification.cs │ │ └── SignupNotification.cs │ ├── Exceptions │ │ └── ValidationException.cs │ └── Models │ │ └── UserInfo.cs ├── Card │ ├── Commands │ │ ├── CreateCardItem │ │ │ ├── CreateCardItemCommand.cs │ │ │ └── CreateCardItemCommandHandler.cs │ │ └── UpdateCardItem │ │ │ ├── UpdateCardItemCommand.cs │ │ │ └── UpdateCardItemCommandHandler.cs │ └── Queries │ │ └── GetCardItems │ │ ├── GetCardItemsQuery.cs │ │ └── GetCardItemsQueryHandler.cs ├── Settings │ └── AppSettings.cs ├── User │ └── Commands │ │ ├── Login │ │ ├── LoginCommand.cs │ │ ├── LoginCommandValidator.cs │ │ └── LoginCommandHandler.cs │ │ └── Register │ │ ├── RegisterCommand.cs │ │ ├── RegisterCommandValidator.cs │ │ └── RegisterComandHandler.cs ├── DependencyInjection.cs └── MAUI.CleanArchitecture.Application.csproj ├── LICENSE ├── README.md ├── MAUI.CleanArchitecture.sln └── .gitignore /MAUI.CleanArchitecture/Configuration/appsettings.debug.json: -------------------------------------------------------------------------------- 1 | { 2 | "ConnectionStrings": { 3 | "DefaultConnection": "Data Source={0}\\store.db" 4 | } 5 | } -------------------------------------------------------------------------------- /MAUI.CleanArchitecture/Configuration/appsettings.release.json: -------------------------------------------------------------------------------- 1 | { 2 | "ConnectionStrings": { 3 | "DefaultConnection": "Data Source={0}store.db" 4 | } 5 | } -------------------------------------------------------------------------------- /MAUI.CleanArchitecture/Resources/Images/login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hflexgrig/MAUI---CleanArchitecture/HEAD/MAUI.CleanArchitecture/Resources/Images/login.png -------------------------------------------------------------------------------- /MAUI.CleanArchitecture/Resources/Images/signup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hflexgrig/MAUI---CleanArchitecture/HEAD/MAUI.CleanArchitecture/Resources/Images/signup.png -------------------------------------------------------------------------------- /MAUI.CleanArchitecture/Resources/Images/add_to_cart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hflexgrig/MAUI---CleanArchitecture/HEAD/MAUI.CleanArchitecture/Resources/Images/add_to_cart.png -------------------------------------------------------------------------------- /MAUI.CleanArchitecture/Resources/Fonts/OpenSans-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hflexgrig/MAUI---CleanArchitecture/HEAD/MAUI.CleanArchitecture/Resources/Fonts/OpenSans-Regular.ttf -------------------------------------------------------------------------------- /MAUI.CleanArchitecture/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "Windows Machine": { 4 | "commandName": "MsixPackage", 5 | "nativeDebugging": false 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /MAUI.CleanArchitecture/AppShell.xaml.cs: -------------------------------------------------------------------------------- 1 | namespace MAUI.CleanArchitecture; 2 | 3 | public partial class AppShell : Shell 4 | { 5 | public AppShell() 6 | { 7 | InitializeComponent(); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /MAUI.CleanArchitecture/Resources/appicon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /MAUI.CleanArchitecture.Domain/MainModel.cs: -------------------------------------------------------------------------------- 1 | namespace MAUI.CleanArchitecture.Domain 2 | { 3 | public class MainModel 4 | { 5 | public int TotalQuantity => SubItems.Sum(x => x.Quantity); 6 | public IList SubItems { get; set; } = new List(); 7 | } 8 | } -------------------------------------------------------------------------------- /MAUI.CleanArchitecture/Platforms/Android/Resources/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #512BD4 4 | #2B0B98 5 | #2B0B98 6 | -------------------------------------------------------------------------------- /MAUI.CleanArchitecture.Domain/MAUI.CleanArchitecture.Domain.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net6.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /MAUI.CleanArchitecture/Utils/IPageManager.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | 3 | namespace MAUI.CleanArchitecture.Utils 4 | { 5 | public interface IPageManager 6 | { 7 | Task PopPageAsync(); 8 | Task PopToRootPageAsync(); 9 | Task StartPageAsync(bool isModal = false); 10 | } 11 | } -------------------------------------------------------------------------------- /MAUI.CleanArchitecture/Controls/CustomStepper.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Maui.Controls; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace MAUI.CleanArchitecture.Controls 9 | { 10 | internal class CustomStepper:Stepper 11 | { 12 | 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /MAUI.CleanArchitecture.Infrastructure/Persistence/Constants.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace MAUI.CleanArchitecture.Infrastructure.Persistence 8 | { 9 | static class Constants 10 | { 11 | public const string DefaultKey = "Id"; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /MAUI.CleanArchitecture/Platforms/MacCatalyst/AppDelegate.cs: -------------------------------------------------------------------------------- 1 | using Foundation; 2 | using Microsoft.Maui; 3 | using Microsoft.Maui.Hosting; 4 | 5 | namespace MAUI.CleanArchitecture 6 | { 7 | [Register("AppDelegate")] 8 | public class AppDelegate : MauiUIApplicationDelegate 9 | { 10 | protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp(); 11 | } 12 | } -------------------------------------------------------------------------------- /MAUI.CleanArchitecture.Domain/Entities/Rating.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace MAUI.CleanArchitecture.Domain.Entities 8 | { 9 | public class Rating 10 | { 11 | public double Rate { get; set; } 12 | public int Count { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /MAUI.CleanArchitecture/Platforms/Windows/App.xaml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /MAUI.CleanArchitecture.Domain/User/LoginResponseModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace MAUI.CleanArchitecture.Domain.User 8 | { 9 | public class LoginResponseModel 10 | { 11 | public bool IsSucceeded { get; set; } 12 | public string? FailReason { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /MAUI.CleanArchitecture.Domain/SubItem.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace MAUI.CleanArchitecture.Domain 8 | { 9 | public class SubItem 10 | { 11 | public string Name { get; set; } 12 | public string Description { get; set; } 13 | public int Quantity { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /MAUI.CleanArchitecture/Platforms/iOS/Program.cs: -------------------------------------------------------------------------------- 1 | using UIKit; 2 | 3 | namespace MAUI.CleanArchitecture 4 | { 5 | public class Program 6 | { 7 | // This is the main entry point of the application. 8 | static void Main(string[] args) 9 | { 10 | // if you want to use a different Application Delegate class from "AppDelegate" 11 | // you can specify it here. 12 | UIApplication.Main(args, null, typeof(AppDelegate)); 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /MAUI.CleanArchitecture/Platforms/MacCatalyst/Program.cs: -------------------------------------------------------------------------------- 1 | using UIKit; 2 | 3 | namespace MAUI.CleanArchitecture 4 | { 5 | public class Program 6 | { 7 | // This is the main entry point of the application. 8 | static void Main(string[] args) 9 | { 10 | // if you want to use a different Application Delegate class from "AppDelegate" 11 | // you can specify it here. 12 | UIApplication.Main(args, null, typeof(AppDelegate)); 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /MAUI.CleanArchitecture/Platforms/iOS/AppDelegate.cs: -------------------------------------------------------------------------------- 1 | using Foundation; 2 | using Microsoft.Maui; 3 | using Microsoft.Maui.Hosting; 4 | 5 | namespace MAUI.CleanArchitecture 6 | { 7 | [Register("AppDelegate")] 8 | public class AppDelegate : MauiUIApplicationDelegate 9 | { 10 | protected override MauiApp CreateMauiApp() 11 | { 12 | var app = MauiProgram.CreateMauiApp(); 13 | return app; 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /MAUI.CleanArchitecture.Application/Store/Queries/GetStoreItemsQuery/GetStoreItemsQuery.cs: -------------------------------------------------------------------------------- 1 | using MAUI.CleanArchitecture.Domain.Entities; 2 | using MediatR; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace MAUI.CleanArchitecture.Application.Store.Queries.GetStoreItemsQuery 10 | { 11 | public class GetStoreItemsQuery:IRequest> 12 | { 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /MAUI.CleanArchitecture/Platforms/Android/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /MAUI.CleanArchitecture.Infrastructure/Identity/ApplicationUser.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace MAUI.CleanArchitecture.Infrastructure.Identity 8 | { 9 | public class ApplicationUser 10 | { 11 | public string FirstName { get; set; } 12 | public string LastName { get; set; } 13 | 14 | public DateTime DateOfBirth { get; set; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /MAUI.CleanArchitecture.Application/Common/Interfaces/IFakeStoreApiService.cs: -------------------------------------------------------------------------------- 1 | using MAUI.CleanArchitecture.Domain.Entities; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace MAUI.CleanArchitecture.Application.Common.Interfaces 9 | { 10 | public interface IFakeStoreApiService 11 | { 12 | Task> GetStoreItems(CancellationToken cancellationToken); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /MAUI.CleanArchitecture.Application/Card/Commands/CreateCardItem/CreateCardItemCommand.cs: -------------------------------------------------------------------------------- 1 | using MAUI.CleanArchitecture.Domain.Entities; 2 | using MediatR; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace MAUI.CleanArchitecture.Application.Card.Commands.CreateCardItem 10 | { 11 | public class CreateCardItemCommand:IRequest 12 | { 13 | public CardItem CardItem { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /MAUI.CleanArchitecture.Application/Common/Notificications/AddCardItemNotification.cs: -------------------------------------------------------------------------------- 1 | using MAUI.CleanArchitecture.Domain.Entities; 2 | using MediatR; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace MAUI.CleanArchitecture.Application.Common.Notificications 10 | { 11 | public class AddCardItemNotification : INotification 12 | { 13 | public CardItem CardItem { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /MAUI.CleanArchitecture.Application/Common/Notificications/SigninNotification.cs: -------------------------------------------------------------------------------- 1 | using MAUI.CleanArchitecture.Application.Common.Models; 2 | using MediatR; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace MAUI.CleanArchitecture.Application.Common.Notificications 10 | { 11 | public class SigninNotification : INotification 12 | { 13 | public UserInfo? UserInfo { get; internal set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /MAUI.CleanArchitecture.Application/Common/Notificications/SignupNotification.cs: -------------------------------------------------------------------------------- 1 | using MAUI.CleanArchitecture.Application.Common.Models; 2 | using MediatR; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace MAUI.CleanArchitecture.Application.Common.Notificications 10 | { 11 | public class SignupNotification : INotification 12 | { 13 | public UserInfo? UserInfo { get; internal set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /MAUI.CleanArchitecture.Application/Settings/AppSettings.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace MAUI.CleanArchitecture.Application.Settings 8 | { 9 | public class AppSettings 10 | { 11 | public ConnectionStrings ConnectionStrings { get; set; } 12 | 13 | } 14 | 15 | public class ConnectionStrings 16 | { 17 | public string? DefaultConnection { get; set; } 18 | 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /MAUI.CleanArchitecture.Domain/Entities/User.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace MAUI.CleanArchitecture.Domain.Entities 8 | { 9 | public class User 10 | { 11 | public Guid Id { get; set; } 12 | public string UserName { get; set; } 13 | public string Email { get; set; } 14 | public string FirstName { get; set; } 15 | public string LastName { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /MAUI.CleanArchitecture.Application/Card/Commands/UpdateCardItem/UpdateCardItemCommand.cs: -------------------------------------------------------------------------------- 1 | using MAUI.CleanArchitecture.Domain.Entities; 2 | using MediatR; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace MAUI.CleanArchitecture.Application.Card.Commands.CreateCardItem 10 | { 11 | public class UpdateCardItemCommand : IRequest 12 | { 13 | public Guid UserId { get; set; } 14 | public Guid SessionId { get; set; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /MAUI.CleanArchitecture.Application/Card/Queries/GetCardItems/GetCardItemsQuery.cs: -------------------------------------------------------------------------------- 1 | using MAUI.CleanArchitecture.Domain.Entities; 2 | using MediatR; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace MAUI.CleanArchitecture.Application.Card.Queries.GetCardItems 10 | { 11 | public class GetCardItemsQuery : IRequest> 12 | { 13 | public Guid SessionId { get; set; } 14 | public Guid? UserId { get; set; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /MAUI.CleanArchitecture.Application/Common/Exceptions/ValidationException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace MAUI.CleanArchitecture.Application.Common.Exceptions 8 | { 9 | public class ValidationException : Exception 10 | { 11 | public ValidationException(string message) : base(message) 12 | { 13 | 14 | } 15 | 16 | public Dictionary? ValidationErrors { get; set; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /MAUI.CleanArchitecture.Application/Common/Models/UserInfo.cs: -------------------------------------------------------------------------------- 1 | using MediatR; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace MAUI.CleanArchitecture.Application.Common.Models 9 | { 10 | public class UserInfo 11 | { 12 | public bool IsSignedIn { get; internal set; } 13 | public Guid SessionId { get; } = Guid.NewGuid(); 14 | public Domain.Entities.User User { get; internal set; } = new Domain.Entities.User(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /MAUI.CleanArchitecture/Platforms/Android/MainApplication.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Android.App; 3 | using Android.Runtime; 4 | using Microsoft.Maui; 5 | using Microsoft.Maui.Hosting; 6 | 7 | namespace MAUI.CleanArchitecture 8 | { 9 | [Application] 10 | public class MainApplication : MauiApplication 11 | { 12 | public MainApplication(IntPtr handle, JniHandleOwnership ownership) 13 | : base(handle, ownership) 14 | { 15 | } 16 | 17 | protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp(); 18 | } 19 | } -------------------------------------------------------------------------------- /MAUI.CleanArchitecture/AppShell.xaml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /MAUI.CleanArchitecture/Views/ContentViews/CardItemView.xaml.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Maui; 2 | using Microsoft.Maui.Controls; 3 | using Microsoft.Maui.Controls.Xaml; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace MAUI.CleanArchitecture.Views 11 | { 12 | [XamlCompilation(XamlCompilationOptions.Compile)] 13 | public partial class CardItemView : ContentView 14 | { 15 | public CardItemView() 16 | { 17 | InitializeComponent(); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /MAUI.CleanArchitecture/Views/Pages/RegisterPageView.xaml.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Maui; 2 | using Microsoft.Maui.Controls; 3 | using Microsoft.Maui.Controls.Xaml; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace MAUI.CleanArchitecture.Views 11 | { 12 | [XamlCompilation(XamlCompilationOptions.Compile)] 13 | public partial class RegisterPageView : ContentPage 14 | { 15 | public RegisterPageView() 16 | { 17 | InitializeComponent(); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /MAUI.CleanArchitecture.Application/User/Commands/Login/LoginCommand.cs: -------------------------------------------------------------------------------- 1 | using MAUI.CleanArchitecture.Application.Common.Notificications; 2 | using MAUI.CleanArchitecture.Domain.User; 3 | using MediatR; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace MAUI.CleanArchitecture.Application.User.Commands.Login 11 | { 12 | public class LoginCommand:IRequest 13 | { 14 | public string Username { get; set; } 15 | public string Password { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /MAUI.CleanArchitecture.Domain/Entities/CardItem.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace MAUI.CleanArchitecture.Domain.Entities 8 | { 9 | public class CardItem 10 | { 11 | public int Quantity { get; set; } 12 | 13 | public StoreItem StoreItem { get; set; } = new StoreItem(); 14 | 15 | public Guid? UserId { get; set; } 16 | public Guid SessionId { get; set; } 17 | 18 | public decimal CalculatedPrice => StoreItem.Price * Quantity; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /MAUI.CleanArchitecture.Application/User/Commands/Login/LoginCommandValidator.cs: -------------------------------------------------------------------------------- 1 | using FluentValidation; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace MAUI.CleanArchitecture.Application.User.Commands.Login 9 | { 10 | public class LoginCommandValidator:AbstractValidator 11 | { 12 | public LoginCommandValidator() 13 | { 14 | RuleFor(x => x.Username).NotEmpty().MinimumLength(3).MaximumLength(20); 15 | RuleFor(x => x.Password).NotEmpty().MinimumLength(5); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /MAUI.CleanArchitecture.Domain/Entities/StoreItem.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace MAUI.CleanArchitecture.Domain.Entities 8 | { 9 | public class StoreItem 10 | { 11 | public int Id { get; set; } 12 | public string? Title { get; set; } 13 | public decimal Price { get; set; } 14 | public string? Description { get; set; } 15 | public string? Category { get; set; } 16 | public string? Image { get; set; } 17 | public Rating Rating { get; set; } = new Rating(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /MAUI.CleanArchitecture/Views/Pages/MainPageView.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MAUI.CleanArchitecture.ViewModels.Base; 3 | using Microsoft.Maui.Controls; 4 | 5 | namespace MAUI.CleanArchitecture.Views 6 | { 7 | public partial class MainPageView : ContentPage 8 | { 9 | 10 | public MainPageView() 11 | { 12 | InitializeComponent(); 13 | } 14 | 15 | private void NumericStepper_ValueChanged(object sender, ValueChangedEventArgs e) 16 | { 17 | 18 | } 19 | 20 | private void NumericStepper_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) 21 | { 22 | 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /MAUI.CleanArchitecture.Application/Common/Interfaces/IAuthentication.cs: -------------------------------------------------------------------------------- 1 | using MAUI.CleanArchitecture.Application.User.Commands.Login; 2 | using MAUI.CleanArchitecture.Application.User.Commands.Register; 3 | 4 | namespace MAUI.CleanArchitecture.Application.Common.Interfaces 5 | { 6 | public interface IAuthentication 7 | { 8 | Task CheckPassword(string email, string password); 9 | Task CreateUser(RegisterCommand registerCommand); 10 | Task SignInAsync(LoginCommand loginCommand); 11 | Task UpdatePassword(string email, string oldPassword, string newPassword); 12 | } 13 | } -------------------------------------------------------------------------------- /MAUI.CleanArchitecture.Application/Common/Interfaces/IStoreDbContext.cs: -------------------------------------------------------------------------------- 1 | using MAUI.CleanArchitecture.Domain.Entities; 2 | using Microsoft.EntityFrameworkCore; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace MAUI.CleanArchitecture.Application.Common.Interfaces 10 | { 11 | public interface IStoreDbContext 12 | { 13 | DbSet StoreItems { get; set; } 14 | DbSet CardItems { get; set; } 15 | 16 | Task MigrateAsync(CancellationToken token); 17 | Task SaveChangesAsync(CancellationToken cancellationToken); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /MAUI.CleanArchitecture/Resources/Raw/AboutAssets.txt: -------------------------------------------------------------------------------- 1 | Any raw assets you want to be deployed with your application can be placed in 2 | this directory (and child directories). Deployment of the asset to your application 3 | is automatically handled by the following `MauiAsset` Build Action within your `.csproj`. 4 | 5 | 6 | 7 | These files will be deployed with you package and will be accessible using Essentials: 8 | 9 | async Task LoadMauiAsset() 10 | { 11 | using var stream = await FileSystem.OpenAppPackageFileAsync("AboutAssets.txt"); 12 | using var reader = new StreamReader(stream); 13 | 14 | var contents = reader.ReadToEnd(); 15 | } 16 | -------------------------------------------------------------------------------- /MAUI.CleanArchitecture.Infrastructure/Persistence/Configurations/RatingConfiguration.cs: -------------------------------------------------------------------------------- 1 | using MAUI.CleanArchitecture.Domain.Entities; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace MAUI.CleanArchitecture.Infrastructure.Persistence.Configurations 11 | { 12 | public class Ratingfiguration : IEntityTypeConfiguration 13 | { 14 | public void Configure(EntityTypeBuilder builder) 15 | { 16 | builder.Property("StoreRef"); 17 | builder.HasKey("StoreRef"); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /MAUI.CleanArchitecture/Platforms/Android/MainActivity.cs: -------------------------------------------------------------------------------- 1 | using Android.App; 2 | using Android.Content.PM; 3 | using Android.OS; 4 | using Microsoft.Maui; 5 | 6 | namespace MAUI.CleanArchitecture 7 | { 8 | [Activity(Theme = "@style/Maui.SplashTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize)] 9 | public class MainActivity : MauiAppCompatActivity 10 | { 11 | protected override void OnCreate(Bundle savedInstanceState) 12 | { 13 | //Java.Lang.JavaSystem.LoadLibrary("System.Security.Cryptography.Native.OpenSsl"); 14 | base.OnCreate(savedInstanceState); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /MAUI.CleanArchitecture/Converters/DoubleToStringConverter.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Maui.Controls; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Globalization; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace MAUI.CleanArchitecture.Converters 10 | { 11 | public class DoubleToStringConverter : IValueConverter 12 | { 13 | 14 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 15 | { 16 | return value.ToString(); 17 | } 18 | 19 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 20 | { 21 | return System.Convert.ToDouble(value); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /MAUI.CleanArchitecture/Platforms/Windows/app.manifest: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 11 | true/PM 12 | PerMonitorV2, PerMonitor 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /MAUI.CleanArchitecture/Utils/PageManager.cs: -------------------------------------------------------------------------------- 1 | using MAUI.CleanArchitecture.ViewModels.Base; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace MAUI.CleanArchitecture.Utils 9 | { 10 | public class PageManager : IPageManager 11 | { 12 | public Task StartPageAsync(bool isModal = false) 13 | { 14 | return ViewModelLocator.StartPageAsync(isModal); 15 | } 16 | 17 | public Task PopPageAsync() 18 | { 19 | return ViewModelLocator.PopPageAsync(); 20 | } 21 | 22 | public Task PopToRootPageAsync() 23 | { 24 | return ViewModelLocator.PopToRootPageAsync(); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /MAUI.CleanArchitecture.Application/User/Commands/Register/RegisterCommand.cs: -------------------------------------------------------------------------------- 1 | using MAUI.CleanArchitecture.Application.Common.Models; 2 | using MAUI.CleanArchitecture.Application.Common.Notificications; 3 | using MAUI.CleanArchitecture.Domain.User; 4 | using MediatR; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | 11 | namespace MAUI.CleanArchitecture.Application.User.Commands.Register 12 | { 13 | public class RegisterCommand : IRequest 14 | { 15 | public string Username { get; set; } 16 | public string Email { get; set; } 17 | public string Password { get; set; } 18 | 19 | public string FirstName { get; set; } 20 | public string LastName { get; set; } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /MAUI.CleanArchitecture/Views/Pages/LoginPageView.xaml.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Maui; 2 | using Microsoft.Maui.Controls; 3 | using Microsoft.Maui.Controls.Xaml; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace MAUI.CleanArchitecture.Views 11 | { 12 | [XamlCompilation(XamlCompilationOptions.Compile)] 13 | public partial class LoginPageView : ContentPage 14 | { 15 | public LoginPageView() 16 | { 17 | InitializeComponent(); 18 | } 19 | 20 | protected override void OnDisappearing() 21 | { 22 | base.OnDisappearing(); 23 | if(BindingContext is IDisposable vm) 24 | { 25 | vm.Dispose(); 26 | } 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /MAUI.CleanArchitecture.Application/DependencyInjection.cs: -------------------------------------------------------------------------------- 1 | using FluentValidation; 2 | using MAUI.CleanArchitecture.Application.Common.Models; 3 | using MAUI.CleanArchitecture.Application.Settings; 4 | using MediatR; 5 | using Microsoft.Extensions.DependencyInjection; 6 | using System.Reflection; 7 | using System.Text.Json; 8 | 9 | namespace MAUI.CleanArchitecture.Application 10 | { 11 | public static class DependencyInjection 12 | { 13 | public static IServiceCollection AddApplication(this IServiceCollection services) 14 | { 15 | 16 | services.AddMediatR(Assembly.GetExecutingAssembly()); 17 | 18 | services.AddValidatorsFromAssembly(Assembly.GetExecutingAssembly()); 19 | 20 | services.AddSingleton(new UserInfo()); 21 | return services; 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /MAUI.CleanArchitecture/Views/Pages/UserInfoPageView.xaml.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Maui; 2 | using Microsoft.Maui.Controls; 3 | using Microsoft.Maui.Controls.Xaml; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace MAUI.CleanArchitecture.Views 11 | { 12 | [XamlCompilation(XamlCompilationOptions.Compile)] 13 | public partial class UserInfoPageView : ContentPage 14 | { 15 | public UserInfoPageView() 16 | { 17 | InitializeComponent(); 18 | } 19 | 20 | protected override void OnDisappearing() 21 | { 22 | base.OnDisappearing(); 23 | if(BindingContext is IDisposable vm) 24 | { 25 | vm.Dispose(); 26 | } 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /MAUI.CleanArchitecture/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using MAUI.CleanArchitecture.ViewModels.Base; 2 | using MAUI.CleanArchitecture.Views; 3 | using Microsoft.Maui; 4 | using Microsoft.Maui.Controls; 5 | using Microsoft.Maui.Controls.PlatformConfiguration.WindowsSpecific; 6 | 7 | namespace MAUI.CleanArchitecture 8 | { 9 | public partial class App : Microsoft.Maui.Controls.Application 10 | { 11 | public App() 12 | { 13 | InitializeComponent(); 14 | 15 | var mainPage = new AppShell(); 16 | Navigation = new NavigationPage(mainPage); 17 | mainPage.Navigation.InitializeNavigation(); 18 | } 19 | 20 | public NavigationPage Navigation { get; } 21 | 22 | protected override Window CreateWindow(IActivationState activationState) => 23 | new Window(Navigation) { Title = "MAUI.CleanArchitecture" }; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /MAUI.CleanArchitecture.Application/User/Commands/Register/RegisterCommandValidator.cs: -------------------------------------------------------------------------------- 1 | using FluentValidation; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace MAUI.CleanArchitecture.Application.User.Commands.Register 9 | { 10 | public class RegisterCommandValidator:AbstractValidator 11 | { 12 | public RegisterCommandValidator() 13 | { 14 | RuleFor(x => x.Username).NotEmpty().MinimumLength(3).MaximumLength(20); 15 | RuleFor(x => x.Email).NotEmpty().MinimumLength(3).MaximumLength(20); 16 | RuleFor(x => x.Password).NotEmpty().MinimumLength(5); 17 | RuleFor(x => x.FirstName).NotEmpty().MaximumLength(20); 18 | RuleFor(x => x.LastName).NotEmpty().MaximumLength(20); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /MAUI.CleanArchitecture/Converters/ImageSourceConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.IO; 4 | using System.Net; 5 | using System.Net.Http; 6 | 7 | namespace MAUI.CleanArchitecture.Converters; 8 | using Microsoft.Maui.Controls; 9 | 10 | 11 | public class ImageSourceConverter : IValueConverter 12 | { 13 | static readonly HttpClient Client = new(); 14 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 15 | { 16 | if (value == null) 17 | return null; 18 | 19 | var byteArray = Client.GetByteArrayAsync(value.ToString()!).GetAwaiter().GetResult(); 20 | 21 | return ImageSource.FromStream(() => new MemoryStream(byteArray)); 22 | } 23 | 24 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 25 | { 26 | throw new NotImplementedException(); 27 | } 28 | } -------------------------------------------------------------------------------- /MAUI.CleanArchitecture/Controls/Errors.xaml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | 11 | 12 | 13 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /MAUI.CleanArchitecture.Infrastructure/BackgroundServices/DbBackgroundService.cs: -------------------------------------------------------------------------------- 1 | using MAUI.CleanArchitecture.Application.Common.Interfaces; 2 | using Microsoft.Extensions.DependencyInjection; 3 | using Microsoft.Extensions.Hosting; 4 | 5 | namespace MAUI.CleanArchitecture.Infrastructure.BackgroundServices 6 | { 7 | public class DbBackgroundService : BackgroundService 8 | { 9 | private readonly IServiceProvider _serviceProvider; 10 | 11 | public DbBackgroundService(IServiceProvider serviceProvider) 12 | { 13 | _serviceProvider = serviceProvider; 14 | } 15 | 16 | protected override async Task ExecuteAsync(CancellationToken stoppingToken) 17 | { 18 | using (var scope = _serviceProvider.CreateScope()) 19 | { 20 | var dbContext = scope.ServiceProvider.GetRequiredService(); 21 | 22 | await dbContext.MigrateAsync(stoppingToken); 23 | } 24 | 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /MAUI.CleanArchitecture.Application/MAUI.CleanArchitecture.Application.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net6.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /MAUI.CleanArchitecture.Infrastructure/Services/FakeStoreApiService.cs: -------------------------------------------------------------------------------- 1 | using MAUI.CleanArchitecture.Application.Common.Interfaces; 2 | using MAUI.CleanArchitecture.Domain.Entities; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Net.Http.Json; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace MAUI.CleanArchitecture.Infrastructure.Services 11 | { 12 | public class FakeStoreApiService:IFakeStoreApiService 13 | { 14 | private readonly HttpClient _httpClient; 15 | 16 | public FakeStoreApiService(HttpClient httpClient) 17 | { 18 | _httpClient = httpClient; 19 | } 20 | 21 | public async Task> GetStoreItems(CancellationToken cancellationToken) 22 | { 23 | var response = await _httpClient.GetAsync("products", cancellationToken); 24 | return await response.Content.ReadFromJsonAsync>(cancellationToken: cancellationToken); 25 | } 26 | 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /MAUI.CleanArchitecture/Views/Pages/UserInfoPageView.xaml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 13 | 14 | 18 | 19 | -------------------------------------------------------------------------------- /MAUI.CleanArchitecture.Application/Card/Commands/CreateCardItem/CreateCardItemCommandHandler.cs: -------------------------------------------------------------------------------- 1 | using MAUI.CleanArchitecture.Application.Common.Interfaces; 2 | using MediatR; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace MAUI.CleanArchitecture.Application.Card.Commands.CreateCardItem 10 | { 11 | public class CreateCardItemCommandHandler : IRequestHandler 12 | { 13 | private readonly IStoreDbContext _storeDbContext; 14 | 15 | public CreateCardItemCommandHandler(IStoreDbContext storeDbContext) 16 | { 17 | _storeDbContext = storeDbContext; 18 | } 19 | 20 | public async Task Handle(CreateCardItemCommand request, CancellationToken cancellationToken) 21 | { 22 | _storeDbContext.CardItems.Add(request.CardItem); 23 | await _storeDbContext.SaveChangesAsync(cancellationToken); 24 | return Unit.Value; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /MAUI.CleanArchitecture.Infrastructure/Persistence/Configurations/CartItemConfiguration.cs: -------------------------------------------------------------------------------- 1 | using MAUI.CleanArchitecture.Domain.Entities; 2 | using MAUI.CleanArchitecture.Infrastructure.Identity; 3 | using Microsoft.EntityFrameworkCore; 4 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | 11 | namespace MAUI.CleanArchitecture.Infrastructure.Persistence.Configurations 12 | { 13 | public class CartItemConfiguration : IEntityTypeConfiguration 14 | { 15 | public void Configure(EntityTypeBuilder builder) 16 | { 17 | builder.Property("StoreRef"); 18 | builder.HasKey("StoreRef"); 19 | 20 | builder.HasOne(t => t.StoreItem).WithOne().HasForeignKey("CardRef"); 21 | 22 | //var identityUser = "IdentityUser"; 23 | //builder.Property(identityUser); 24 | //builder.HasOne(identityUser).WithMany(); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /MAUI.CleanArchitecture.Infrastructure/Persistence/Configurations/StoreItemConfiguration.cs: -------------------------------------------------------------------------------- 1 | using MAUI.CleanArchitecture.Domain.Entities; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace MAUI.CleanArchitecture.Infrastructure.Persistence.Configurations 11 | { 12 | public class StoreItemConfiguration : IEntityTypeConfiguration 13 | { 14 | public void Configure(EntityTypeBuilder builder) 15 | { 16 | builder.Property(t => t.Id).IsUnicode(true).ValueGeneratedNever(); 17 | builder.HasKey(t => t.Id); 18 | 19 | builder.Property("CardRef"); 20 | builder.HasKey("CardRef"); 21 | 22 | builder.Property(t => t.Title).HasMaxLength(200); 23 | builder.Property(t => t.Price).HasPrecision(18, 2); 24 | 25 | builder.HasOne(t => t.Rating).WithOne().HasForeignKey("StoreRef"); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /MAUI.CleanArchitecture/Platforms/MacCatalyst/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | UIDeviceFamily 6 | 7 | 1 8 | 2 9 | 10 | UIRequiredDeviceCapabilities 11 | 12 | arm64 13 | 14 | UISupportedInterfaceOrientations 15 | 16 | UIInterfaceOrientationPortrait 17 | UIInterfaceOrientationLandscapeLeft 18 | UIInterfaceOrientationLandscapeRight 19 | 20 | UISupportedInterfaceOrientations~ipad 21 | 22 | UIInterfaceOrientationPortrait 23 | UIInterfaceOrientationPortraitUpsideDown 24 | UIInterfaceOrientationLandscapeLeft 25 | UIInterfaceOrientationLandscapeRight 26 | 27 | XSAppIconAssets 28 | Assets.xcassets/appicon.appiconset 29 | 30 | 31 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Hayk Hakob Grigoryan 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /MAUI.CleanArchitecture.Application/Card/Queries/GetCardItems/GetCardItemsQueryHandler.cs: -------------------------------------------------------------------------------- 1 | using MAUI.CleanArchitecture.Application.Common.Interfaces; 2 | using MAUI.CleanArchitecture.Domain.Entities; 3 | using MediatR; 4 | using Microsoft.EntityFrameworkCore; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | 11 | namespace MAUI.CleanArchitecture.Application.Card.Queries.GetCardItems 12 | { 13 | public class GetCardItemsQueryHandler : IRequestHandler> 14 | { 15 | private readonly IStoreDbContext _storeDbContext; 16 | 17 | public GetCardItemsQueryHandler(IStoreDbContext storeDbContext) 18 | { 19 | _storeDbContext = storeDbContext; 20 | } 21 | 22 | public Task> Handle(GetCardItemsQuery request, CancellationToken cancellationToken) 23 | { 24 | return _storeDbContext.CardItems.AsNoTracking().Include(x => x.StoreItem) 25 | .Where(x => x.UserId == request.UserId || x.SessionId == request.SessionId) 26 | .ToListAsync(cancellationToken); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /MAUI.CleanArchitecture.Infrastructure/MAUI.CleanArchitecture.Infrastructure.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net6.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /MAUI.CleanArchitecture/ViewModels/Base/ViewModelBase.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.ComponentModel; 5 | using System.Linq; 6 | using System.Runtime.CompilerServices; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace MAUI.CleanArchitecture.ViewModels.Base 11 | { 12 | public class ViewModelBase : INotifyPropertyChanged 13 | { 14 | public event PropertyChangedEventHandler PropertyChanged; 15 | private IEnumerable _errors; 16 | 17 | public virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) => 18 | PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 19 | 20 | public IEnumerable Errors 21 | { 22 | get => _errors; set 23 | { 24 | _errors = value; 25 | OnPropertyChanged(); 26 | } 27 | } 28 | 29 | private IEnumerable _customErrors; 30 | 31 | public IEnumerable CustomErrors 32 | { 33 | get { return _customErrors; } 34 | set { _customErrors = value; OnPropertyChanged(); } 35 | } 36 | 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /MAUI.CleanArchitecture.Application/Store/Queries/GetStoreItemsQuery/GetStoreItemsQueryHandler.cs: -------------------------------------------------------------------------------- 1 | using MAUI.CleanArchitecture.Application.Common.Interfaces; 2 | using MAUI.CleanArchitecture.Domain.Entities; 3 | using MediatR; 4 | using Microsoft.EntityFrameworkCore; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | 11 | namespace MAUI.CleanArchitecture.Application.Store.Queries.GetStoreItemsQuery 12 | { 13 | public class GetStoreItemsQueryHandler : IRequestHandler> 14 | { 15 | private readonly IFakeStoreApiService _fakeStoreApiService; 16 | private readonly IStoreDbContext _storeDbContext; 17 | 18 | public GetStoreItemsQueryHandler(IFakeStoreApiService fakeStoreApiService, IStoreDbContext storeDbContext) 19 | { 20 | _fakeStoreApiService = fakeStoreApiService; 21 | _storeDbContext = storeDbContext; 22 | } 23 | 24 | public Task> Handle(GetStoreItemsQuery request, CancellationToken cancellationToken) 25 | { 26 | return _fakeStoreApiService.GetStoreItems(cancellationToken); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /MAUI.CleanArchitecture.Application/Card/Commands/UpdateCardItem/UpdateCardItemCommandHandler.cs: -------------------------------------------------------------------------------- 1 | using MAUI.CleanArchitecture.Application.Common.Interfaces; 2 | using MediatR; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace MAUI.CleanArchitecture.Application.Card.Commands.CreateCardItem 10 | { 11 | public class UpdateCardItemCommandHandler : IRequestHandler 12 | { 13 | private readonly IStoreDbContext _storeDbContext; 14 | 15 | public UpdateCardItemCommandHandler(IStoreDbContext storeDbContext) 16 | { 17 | _storeDbContext = storeDbContext; 18 | } 19 | 20 | public async Task Handle(UpdateCardItemCommand request, CancellationToken cancellationToken) 21 | { 22 | var cardItems = _storeDbContext.CardItems.Where(x => x.SessionId == request.SessionId); 23 | foreach (var cardItem in cardItems) 24 | { 25 | cardItem.UserId = request.UserId; 26 | } 27 | 28 | await _storeDbContext.SaveChangesAsync(cancellationToken); 29 | return Unit.Value; 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /MAUI.CleanArchitecture/Platforms/iOS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | LSRequiresIPhoneOS 6 | 7 | UIDeviceFamily 8 | 9 | 1 10 | 2 11 | 12 | UIRequiredDeviceCapabilities 13 | 14 | arm64 15 | 16 | UISupportedInterfaceOrientations 17 | 18 | UIInterfaceOrientationPortrait 19 | UIInterfaceOrientationLandscapeLeft 20 | UIInterfaceOrientationLandscapeRight 21 | 22 | UISupportedInterfaceOrientations~ipad 23 | 24 | UIInterfaceOrientationPortrait 25 | UIInterfaceOrientationPortraitUpsideDown 26 | UIInterfaceOrientationLandscapeLeft 27 | UIInterfaceOrientationLandscapeRight 28 | 29 | XSAppIconAssets 30 | Assets.xcassets/appicon.appiconset 31 | CFBundleIdentifier 32 | com.companyname.MAUI.CleanArchitecture 33 | 34 | 35 | -------------------------------------------------------------------------------- /MAUI.CleanArchitecture.Application/User/Commands/Login/LoginCommandHandler.cs: -------------------------------------------------------------------------------- 1 | using MAUI.CleanArchitecture.Application.Common.Interfaces; 2 | using MAUI.CleanArchitecture.Application.Common.Models; 3 | using MAUI.CleanArchitecture.Application.Common.Notificications; 4 | using MAUI.CleanArchitecture.Domain.User; 5 | using MediatR; 6 | using System; 7 | using System.Collections.Generic; 8 | using System.Linq; 9 | using System.Text; 10 | using System.Threading.Tasks; 11 | 12 | namespace MAUI.CleanArchitecture.Application.User.Commands.Login 13 | { 14 | public class LoginCommandHandler : IRequestHandler 15 | { 16 | private readonly IAuthentication _authentication; 17 | private readonly UserInfo _userInfo; 18 | 19 | public LoginCommandHandler(IAuthentication authentication, UserInfo userInfo) 20 | { 21 | _authentication = authentication; 22 | _userInfo = userInfo; 23 | } 24 | 25 | public async Task Handle(LoginCommand request, CancellationToken cancellationToken) 26 | { 27 | var user = await _authentication.SignInAsync(request); 28 | _userInfo.User = user; 29 | _userInfo.IsSignedIn = true; 30 | return new SigninNotification { UserInfo = _userInfo }; 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /MAUI.CleanArchitecture.Application/User/Commands/Register/RegisterComandHandler.cs: -------------------------------------------------------------------------------- 1 | using MAUI.CleanArchitecture.Application.Common.Interfaces; 2 | using MAUI.CleanArchitecture.Application.Common.Models; 3 | using MAUI.CleanArchitecture.Application.Common.Notificications; 4 | using MAUI.CleanArchitecture.Domain.User; 5 | using MediatR; 6 | using System; 7 | using System.Collections.Generic; 8 | using System.Linq; 9 | using System.Text; 10 | using System.Threading.Tasks; 11 | 12 | namespace MAUI.CleanArchitecture.Application.User.Commands.Register 13 | { 14 | public class RegisterCommandHandler : IRequestHandler 15 | { 16 | private readonly IAuthentication _authentication; 17 | private readonly UserInfo _userInfo; 18 | 19 | public RegisterCommandHandler(IAuthentication authentication, UserInfo userInfo) 20 | { 21 | _authentication = authentication; 22 | _userInfo = userInfo; 23 | } 24 | 25 | public async Task Handle(RegisterCommand request, CancellationToken cancellationToken) 26 | { 27 | var user = await _authentication.CreateUser(request); 28 | _userInfo.User = user; 29 | _userInfo.IsSignedIn = true; 30 | 31 | return new SignupNotification { UserInfo = _userInfo}; 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /MAUI.CleanArchitecture/Platforms/Windows/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Maui; 2 | using Microsoft.Maui.Hosting; 3 | using Microsoft.UI.Xaml; 4 | using Windows.ApplicationModel; 5 | 6 | // To learn more about WinUI, the WinUI project structure, 7 | // and more about our project templates, see: http://aka.ms/winui-project-info. 8 | 9 | namespace MAUI.CleanArchitecture.WinUI 10 | { 11 | /// 12 | /// Provides application-specific behavior to supplement the default Application class. 13 | /// 14 | public partial class App : MauiWinUIApplication 15 | { 16 | /// 17 | /// Initializes the singleton application object. This is the first line of authored code 18 | /// executed, and as such is the logical equivalent of main() or WinMain(). 19 | /// 20 | public App() 21 | { 22 | this.InitializeComponent(); 23 | } 24 | 25 | protected override MauiApp CreateMauiApp() 26 | { 27 | var app = MauiProgram.CreateMauiApp(); 28 | //app.StartAsync().GetAwaiter().GetResult(); 29 | return app; 30 | } 31 | 32 | protected override void OnLaunched(LaunchActivatedEventArgs args) 33 | { 34 | base.OnLaunched(args); 35 | 36 | // Microsoft.Maui.Essentials.Platform.OnLaunched(args); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /MAUI.CleanArchitecture/App.xaml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 10 | #512bdf 11 | White 12 | 13 | 17 | 18 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /MAUI.CleanArchitecture/Views/Pages/LoginPageView.xaml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |