{"id":14965173,"url":"https://github.com/kauemiziara/cs-sensor-list","last_synced_at":"2026-01-04T09:04:30.785Z","repository":{"id":179773474,"uuid":"658154956","full_name":"KaueMiziara/cs-sensor-list","owner":"KaueMiziara","description":"A desktop application to catalog electronic sensors with CRUD functionalities.","archived":false,"fork":false,"pushed_at":"2024-09-14T20:45:17.000Z","size":165,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-01-31T07:03:05.998Z","etag":null,"topics":["avalonia","avaloniaui","crud","csharp","mariadb","mvvm","sql"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/KaueMiziara.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-06-25T00:17:15.000Z","updated_at":"2025-01-08T11:24:33.000Z","dependencies_parsed_at":"2024-10-10T19:41:07.640Z","dependency_job_id":"0c19839f-5ff5-4e61-bf16-8de85793f62f","html_url":"https://github.com/KaueMiziara/cs-sensor-list","commit_stats":{"total_commits":26,"total_committers":2,"mean_commits":13.0,"dds":"0.11538461538461542","last_synced_commit":"3c956451da619b0f4d73f5827acd17f0977cf9a5"},"previous_names":["kauemiziara/ksensor-list"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KaueMiziara%2Fcs-sensor-list","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KaueMiziara%2Fcs-sensor-list/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KaueMiziara%2Fcs-sensor-list/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KaueMiziara%2Fcs-sensor-list/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/KaueMiziara","download_url":"https://codeload.github.com/KaueMiziara/cs-sensor-list/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":238128504,"owners_count":19421048,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["avalonia","avaloniaui","crud","csharp","mariadb","mvvm","sql"],"created_at":"2024-09-24T13:34:19.347Z","updated_at":"2025-10-25T11:30:56.750Z","avatar_url":"https://github.com/KaueMiziara.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Sensor List in Avalonia\n\n## Table of Contents\n\n- [Introduction](#introduction)\n- [Project Setup](#project-setup)\n- [Backend Setup](#backend-setup)\n  - [DBContext Implementation](#dbcontext-implementation) \n  - [Sensor Model](#sensor-model)\n  - [Repository Implementation](#repository-implementation)\n- [Frontend Setup](#frontend-setup)\n  - [SensorItem](#sensoritem) \n  - [MainWindow](#mainwindow)\n  - [CreateSensor](#createsensor)\n- [CRUD Functionality](#crud-functionality)\n    - [Repository Implementations](#repository-implementations)\n    - [Binding and Validations](#bindings-and-validations)\n- [Conclusion](#conclusion)\n\n\n## Introduction\nI have a collection of electronic sensors that I use for\nvarious purposes, and was keeping track of them using a\nsimple text file. This project aims to provide a better\norganization method by leveraging a database to store the\nsensor items and creating a user-friendly frontend to display\nthem as a list.\n\nBy developing this project, I hope to showcase my ability to\nwork with databases, implement CRUD operations and design a\nfunctional (although not visually appealing) user interface.\nIt serves as a practical solution to my own organizational\nneeds while also demonstrating my programming skills.\n\nThroughout this project, I tried to follow best practices,\nincorporate design patterns, and make use of the C# language\nfeatures and frameworks to create a clean and maintainable\ncodebase.\n\n## Project Setup\nTo ensure the separation of concerns and maintain a modular\ncodebase, this project will adhere to the Model-View-ViewModel\n(MVVM) architecture pattern. MVVM promotes a clear separation\nbetween the user interface (View), the data and logic (Model),\nand the intermediary layer that connects them (ViewModel).\n\nFor the frontend development, I chose to utilize the Avalonia\nFramework, a WPF (Windows Presentation Foundation) inspired \ncross-platform UI framework that enables the creation of\nresponsive desktop applications. With Avalonia,\nI can build the user interface components and easily integrate\nthem with the rest of the application.\n\nOn the backend side, I established the database connection\nusing Entity Framework Core. This ORM (Object-Relational\nMapping) framework simplifies the interaction with the\ndatabase by providing a higher-level abstraction.\nEFCore allows me to define the data model,\nperform database operations, and handle data persistence\nin a convenient and efficient manner.\n\n## Backend Setup\nThe backend of the project involves the creation of a\nModel class, a DBContext class to handle the database\nconnection,and a Repository class responsible for executing\nSQL queries.\n\n### DBContext Implementation\nThe DBContext class serves as the bridge between the\napplication and the database. It inherits from EF Core's\nDBContext class and overrides the OnConfiguring method,\nwhich is called when the DBContext is being configured.\n\nIn the OnConfiguring method, an OptionsBuilder instance is\npassed as a parameter. Using the OptionsBuilder, we define\nthe database to be used and provide the connection string.\n\nOriginally, the project utilized SQLite, which creates a\nlocal database for the application. However, during testing,\nit was observed that the application encountered issues\nfinding the table in the database when running from the IDE\nor in release mode. To overcome this issue, the decision was\nmade to switch the database to MariaDB, which was already\ninstalled on my local machine.\n\nTo protect information such as the database password,\nthe connection string was encapsulated within a hidden\nConnection class. Make sure to replace the properties in the\nConnection class with your actual connection string.\nFor MySQL or MariaDB, the connection string follows this\ntemplate:\n\n```csharp\n\"server={serverAddress};port={serverPort};database={databaseName};user={username};password={userPassword}\"\n```\n\n### Sensor Model\nThe Sensor model represents an item in the database table.\nThe class properties will be used by Entity Framework to\ncreate the corresponding columns in the database table based\non the attributes specified.\n\nA sensor should have the following properties:\n\n- An auto-incrementing ID to serve as the primary key;\n- A non-null name string to identify the sensor;\n- A non-null category string to categorize the sensor;\n- An amount property, which is a non-negative integer and\ndefaults to 0;\n\nThe attributes specified on the properties of the Sensor\nmodel class inform Entity Framework how to map the properties\nto the corresponding columns in the database table.\n\n### Repository Implementation\nThe Repository class serves as the Data Access Layer,\nresponsible for handling database read and write operations\nthrough C# code.\n\nThis class implements methods to perform Create, Read,\nUpdate, and Delete (CRUD) functionalities. The Repository\nclass interacts with the DBContext to execute SQL queries\nand manipulate the data stored in the database.\n\nBy implementing the Repository pattern, we can encapsulate\nthe data access logic and provide a clear separation between\ndata operations and other application layers, allowing a\nmore maintainable code.\n\nThe CRUD functionalities will be detailed in the upcoming\nsections, demonstrating how the Repository class interacts\nwith the database and how data is retrieved and manipulated.\n\n## Frontend Setup\nThe frontend of this project involves the Views and their\ncorresponding ViewModels, which define the user interface\nand handle the binding with the backend.\n\n### SensorItem\nThe SensorItemView is the visual representation of\na single sensor item in the application. It is an AXML file\nthat defines the layout, controls, and data bindings required\nto display the sensor item information.\n\nThe SensorItemViewModel is associated with this view to \nprovide the necessary data and logic from the backend\nfor interacting with the sensor item.\n\n### MainWindow\nThe MainWindow is the main screen of the application that\ndisplays a list of all the sensors. It is also an AXML file\nthat defines the overall layout and structure of the main\nwindow.\n\nThe MainWindowViewModel is associated with this view and\nserves as the intermediary between the UI and the backend\nlogic. It provides the necessary functionality to load the\nsensors, perform search operations and handle user\ninteractions.\n\n### CreateSensor\nThe CreateSensorView is responsible for capturing user input\nto create a new sensor item. It allows users to enter the\nname, category and amount for the new sensor.\n\nThis view is associated with the CreateSensorViewModel, wich\nhandles the creation of the sensor item and updates the\nbackend accordingly. It also includes input controls and\nvalidation logic to ensure the entered data is valid before\ncreating the sensor. \n\n## CRUD Functionality\nThe CRUD operations are essential for managing the sensor \nitems in the application. These operatoins involve both the\nRepository implementation on the backend and the bindings\nand validations made in the Views and ViewModels.\n\n### Repository Implementations\nIt interacts with the DBContext to perform the necessary \ndatabase operations.\nThis section will details each CRUD functionality\nimplementation.\n\n#### Read\n- The GetAllSensors method retrieves all the sensor items from \nthe database. It uses the SensorDbContext to query the Sensors\ntable and returns the result as a list of Sensor objects.\n\n- The GetSensorByName method takes a name parameter and \nretrieves the sensor items whose names contain the specified\nvalue. It performs a LINQ query on the Sensors table using \nthe SensorDbContext and returns the matching sensor items.\n\n- The GetSensorByCategory method takes a category parameter and \nretrieves the sensor items that belong to the specified \ncategory. It filters the Sensors table using a LINQ query \nand returns the matching sensor items.\n\n#### Create\nThe AddSensor method is responsible for creating a new sensor\nitem and adding it to the database. It takes a Sensor object\nas a parameter and performs the following steps:\n\n- Checks if the name or category of the sensor is null or \nempty. If either of them is, an ArgumentException is thrown.\n\n- Validates that the amount of the sensor is not negative.\nIf it is negative, an ArgumentOutOfRangeException is thrown.\n\n- Checks if a sensor with the same name already exists in the\ndatabase. If a duplicate name is found, an ArgumentException \nis thrown.\n\nIf all validations pass, the sensor is added to the Sensors \ntable using the SensorDbContext, and the changes are saved to\nthe database.\n\n#### Update\nThe UpdateSensor method is responsible for updating an \nexisting sensor item in the database. It takes a Sensor \nobject as a parameter and performs the following steps:\n\n- Checks if the name or category of the sensor is null or \nempty. If either of them is, an ArgumentException is thrown.\n\n- Updates the corresponding sensor object in the Sensors\ntable using the SensorDbContext and saves the changes to \nthe database.\n\n#### Delete\nThe DeleteSensor method is responsible for deleting a sensor \nitem from the database. It takes a Sensor object as a \nparameter and performs the following steps:\n\n- Removes the sensor object from the Sensors table using the\nSensorDbContext and saves the changes to the database.\n\n### Bindings and Validations\n- In the MainWindowView, the sensor items are displayed in \na ListBox. The ItemsSource property of the ListBox is bound\nto a collection of sensors in the MainWindowViewModel. This\nbinding ensures that any changes in the sensor collection are\nreflected in the ListBox.\n\n- The MainWindowView also contains a search TextBox and to\nfilter the sensor items. The Text property of the TextBox \nis bound to the SearchName property in the MainWindowViewModel,\nallowing real-time updates as the user types.\n\n- The CreateSensorView contains input fields for the name,\ncategory, and amount of the sensor. The Text properties of \nthe input fields are bound to corresponding properties in\nthe CreateSensorViewModel, enabling two-way data binding \nbetween the user input and the ViewModel. The CreateSensorView\nalso includes a Save button, which triggers the creation of \na new sensor item by invoking a command in the \nCreateSensorViewModel.\n\n- In the SensorItemView, the Delete button is bound to a\ncommand in the SensorItemViewModel, which initiates the \ndeletion of the corresponding sensor item from the database.\n\nFurthermore, in the CreateSensorViewModel, there are\nvalidation checks to ensure that the name and category\nfields are not null or empty. If these fields are not valid,\nappropriate error messages are displayed in the View\nto provide feedback to the user.\n\nBy establishing these bindings and validations between\nthe frontend and backend components, we ensure integrity\nand consistency of the data managed by the application.\n\n## Conclusion\nIn this project, I have developed a desktop application\nusing C# and Avalonia to create a sensor cataloging\nsystem. The application allows me to manage my sensors\nby storing them in a database and providing a\nuser-friendly interface to view, search, create, update,\nand delete items.\n\nBy following the MVVM architecture pattern, I separated\nthe concerns of the backend and frontend components, \npromoting code organization and maintainability. \n\nThe backend utilizes Entity Framework Core and a repository\npattern to handle database operations, while the frontend\nemploys Avalonia Views and ViewModels to provide a user\ninterface and easy data binding.\n\nThroughout the development process, I tried to adhere best\npractices such as using appropriate design patterns, \nfollowing coding conventions, and incorporating error \nhandling and data validation techniques.\n\nAlthough this project focused on a specific use case of \ncataloging sensors, the principles and techniques employed \ncan be applied to other similar applications and serve as a\nfoundation for further learning and development. \n\nBy embracing good coding practices and continuously \nenhancing our programming skills, we can strive towards\nbecoming proficient software developers capable of tackling \nmore complex projects.\n\nOverall, this project has provided me with hands-on\nexperience in C# programming, database integration,\nUI design and application development using the MVVM\npattern.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkauemiziara%2Fcs-sensor-list","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkauemiziara%2Fcs-sensor-list","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkauemiziara%2Fcs-sensor-list/lists"}