Generating Seed Data

Last week was a wonderful learning experience for me as I dived into the subject of seed data thanks to Mr. Peter’s introduction. Seed data plays a crucial role in providing initial data to an application, which helps developers to interact with the system and understand the user experience before actual user data is available.

Mr. Peter patiently guided me through the process of creating seed data, starting with a practical example. To generate the seed data, we employed a function along with ‘for’ loops. This combination allowed us to efficiently produce a specific amount of data for a particular entity. One fascinating aspect was the utilization of GUIDs (Globally Unique Identifiers) to generate unique data. We organized this seed data generation process within a dedicated view model, specially designed for creating seed data.

With the essential data initialized, I proceeded to create the corresponding view. Keeping it simple yet effective, I added a button for each entity that I intended to populate with seed data. This approach allowed me to generate the desired amount of data for each entity with just a click of a button.

Prior to testing the application, I made sure to register the navigation, ensuring that users could seamlessly navigate through the application once the seed data was in place. However, an unexpected hurdle surfaced when I mistakenly clicked on “clean solution” while trying to build the application. This action inadvertently wiped out some of the previously set up configurations, resulting in a debugging session. Fortunately, the difficulties were fixed and the appropriate settings were restored with thanks to the help of Mr Peter.

Despite the hiccup, I was determined to further explore the benefits of seed data and decided to create seed data for another entity. This provided me with additional hands-on experience, and I gained a deeper understanding of how seed data can streamline the testing and development process, making it an indispensable tool in the application development journey.

Replacing the Old Data Transfer Object (DTO) of an Entity

Last week, I embarked on a task that involved replacing an old Data Transfer Object (DTO) for a particular entity, along with its associated address and contact DTOs. The process of updating the DTO also required me to adjust the mappings inside the services, since the old DTO used manual mapping, which I switched to using AutoMapper.

Additionally, as I proceeded with the replacement of the old DTO, I also diligently worked in debug mode, resolving errors in parallel. This approach allowed me to identify and rectify any issues that arose during the transition to the new DTOs. By addressing errors promptly, I ensured a smoother and more efficient integration of the updated DTOs into the existing codebase.

During the initial stages, I was eager to replace multiple DTOs, believing it would lead to a more refined codebase. However, Mr. Peter’s cautioned me from this approach. He advised me to focus solely on the current entity’s DTO, cautioning against unnecessary complexities that might arise from altering multiple DTOs simultaneously. This guidance had helped me maintain a more targeted and manageable scope for the task.

As I delved deeper into the task, I realized the opportunity to optimize my code further. A comprehensive review of my DTO codes enabled me to identify and remove unnecessary DTOs that I had initially considered adding. Eliminating these extraneous DTOs, which added little value to the overall structure, resulted in a more concise and easier-to-maintain codebase.

Last but not least, the changes in DTOs prompted me to reassess the services in the application. I transitioned the service that was being called directly accessing the database to the ones which utilize API connections.

Code Clean Up : Post-Code Review Session

Reflecting on the productive week that passed, I found myself engrossed in undertaking meticulously cleaning up the codebase following an extensive code review session with Mr. Peter. This session encompassed not only the application but also into the user interface. Mr. Peter thoroughly analyzes each and every line of code, ensuring its readability and maintainability for future utilization.

Throughout the session, Mr. Peter had taught me with valuable insights that enriched my understanding of the principles behind writing clean code. Initially, I had held the belief that it was best practice to encompass the entire usage of an entity within the create, update, and delete commands and queries. I had reasoned that by doing so, future developers would be relieved of the burden of defining or initializing them again. However, under Mr. Peter’s guidance, I realized the importance of minimizing the code to include only what is truly necessary, thereby reducing unnecessary clutter and improving overall code efficiency.

One specific aspect that came to light during the review process was the handling of query lists. It dawned on me that it was sufficient to define only the data that would be displayed on the screen or required to be passed to the user interface. This realization enabled me to streamline the code, eliminating any extraneous information and ensuring that it remains concise and purposeful.

As the week progressed and various code cleaning tasks were successfully accomplished, I approached the final assignment at hand, which is the replacement of old DTOs with newer versions. However, in the midst of this process, I encountered a minor setback. I mistakenly attempted to modify a specific element that Mr. Peter promptly clarified that it should not be altered at this stage. He explained that making such changes would necessitate significant code modifications, better suited for future endeavors.

Despite this slight misstep, I am grateful for the wealth of knowledge gained during the code review session. It truly cultivated a deeper understanding of the importance of code cleanliness, readability, and maintainability.

Add-Migration and Code Reviews

Last week, I had the opportunity to apply my knowledge on EF Core’s Add-Migration command. Add-Migration is a command provided by Entity Framework Core (EF Core) that allows a developer to create a new migration based on the changes made to database context. People use Add-Migration when they need to update their database schema to reflect changes made in their application’s data model. The reason I was told to use Add-migration was because I needed to add a new data field into the data model for an entity.

To my surprise, using Add-Migration turned out to be much easier than I anticipated. I took a cue from the previous commit and used it as a reference, ensuring I was on the right track. I also sought clarification from Mr. Peter to verify my understanding of the steps involved. First things first, I initialized the new data field in all the necessary commands: create, update, delete, and query. It was crucial to ensure that the new field was properly integrated into all aspects of data manipulation. Consequently, I diligently updated the tests for create, update, delete, and query until each test passed successfully. 

Moving on to the user interface (UI), I introduced an interface for the new data field, making sure to bind it correctly. It was important to create a seamless connection between the UI and the underlying application logic. With the interface in place, I proceeded to establish the mapping connection both at the application level and within the user interface, ensuring the new field’s values flowed smoothly between the two.

Additionally, I paid attention to the configuration entity responsible for handling its connection. This configuration entity played a vital role in configuring the entity’s properties, relationships, and constraints using EF Core’s Fluent API. I made sure to incorporate the new data field into this entity’s configuration, ensuring its proper representation within the database schema.

With everything set and ready to go, I opened up the Package Manager Console and eagerly executed the command ‘Add-Migration <the migration name>’ and then applied the migration using the ‘Update-Database’ command. This command executed the migration script, effectively creating a new data field table in the database with all the necessary changes incorporated.

Later that week, I had a helpful code review session with Mr. Peter. He carefully reviewed my code and pointed out some mistakes I had made. He also gave me valuable advice on how to write better code. One important lesson I learned from Mr. Peter is the significance of paying attention to every detail when writing code. He stressed that each line of code matters and should be written with care. It’s crucial to write code that is easy to read, understand, and maintain. It became evident that thoroughness and precision in coding were key factors in ensuring the reliability and efficiency of our applications. In a nutshell, my journey with EF Core’s Add-Migration command and the insightful code review session have been immensely valuable and I’m excited to continue applying these lessons in my future coding endeavors.

Optimizing User Interface

In my previous blog post, I shared the difficulties I encountered while working on the contact management functionality. Specifically, I was facing challenges in enabling the ability to delete and update contacts in the contact list. Initially, my assumption was that the issue lay within the code responsible for updating the data in the database. My thoughts were that I might be missing a few code that is crucial for updating to the database. 

After Mr. Peter reviewed the code, it was discovered that the main reason for the problem was the incorrect usage of a specific function. Specifically, instead of using the “Get contact by Id” function from the entity service, I had been using the “Read contact by Id” function. This incorrect usage of the function was causing the problem I was experiencing. In cases where modifications to the database were required, it was crucial to use the “Get” function. The key difference between the two functions was that the “Read” function utilized the “.AsNoTracking” feature, which instructed the code not to track any changes made. In my specific scenario, where updates and deletions needed to be reflected in the database, employing the “Get” function was imperative.

Next, I proceeded to the next task on my agenda, which focused on optimizing the user interface. The first part of this endeavor involved making subtle but impactful modifications to the contact list interface. I paid close attention to the area where users added new contacts, ensuring that the process was intuitive and streamlined.

The following task is to make the UI non-editable while users are in view mode. This aspect allowed me to implement and gain a better understanding of what data binding can do. I used binding to change the IsReadOnly property of TextBox elements based on their current mode. When in view mode, I set IsReadOnly to true, effectively preventing users from making any inadvertent changes. Conversely, in edit mode, I set IsReadOnly to false, empowering users to modify the necessary information.

During this process, Mr. Peter also enlightened me about another valuable feature related to buttons. Specifically, he shared about how buttons could be dynamically hidden in certain scenarios. This feature proved particularly useful in scenarios where certain buttons were unnecessary or irrelevant, allowing for a cleaner and more focused user experience.

Adding a New Data Field


Last week was quite eventful for me as I took on the task of adding a new data field to an entity in my project. Specifically, I wanted to focus on the address of the entity within the entity’s details. Fortunately, the entity’s address was already present in the user interface (UI), so my main objective was to ensure that the address entered by the user was being handled accurately when interacting with the database and when passing it back to the front-end.

To accomplish this, I started by working on the backend. Using the powerful CQRS pattern, I initialized the entity’s address within the create and update commands, as well as the get by ID query. Additionally, I established the necessary mapping connection within the entity’s profile. This backend setup was crucial in ensuring smooth data flow.

Moving on to the UI, I wanted to make the user experience seamless and error-free. I began by initializing the address within the entity’s DTO wrapper and the corresponding list. Furthermore, I ensured that the mapping connection was properly configured within the entity’s profile. I also took the opportunity to improvise and modify the existing state management and to facilitate the interaction of the address in the entity’s detail view model. This view model is responsible for presenting the entity’s detailed information on the frontend.

Eager to see the results, I ran the application and dove into the debugging phase. Initially, things seemed to be progressing well. However, I soon encountered a bug that left me puzzled about its origin. Thankfully, Mr. Peter suggested that I check the entity’s tests to determine if they were passing. It turned out that a few tests were unsuccessful, which gave me valuable insights and a new starting point to resolve the bug. Mr Peter also emphasized the significance of functional tests, not only that it can help me for bug resolution, but also for long-term benefits in future development efforts.

As the week drew to a close, there was one lingering issue that I had not been able to resolve. Whenever I attempted to remove contacts from the contact list, the database failed to update accordingly. This resulted in the unchanged and unremoved contacts persisting in the database. It was a perplexing problem, but one that I was determined to tackle head-on. This week, my primary focus will be on debugging and resolving this issue, with the goal of resolving it within a day.

In summary, last week was filled with progress and challenges. I successfully integrated a new data field into the entity, ensuring that user-entered addresses were handled correctly. While I faced some unexpected bugs, the process of debugging and testing has provided me with valuable insights for moving forward.

Implementing an API Layer Within the View Model

Over the past two weeks, I have been thoroughly exploring the user interface. During the previous week, I was assigned a task by Mr. Peter to modify the way our system interacts with the database within the MVVM architecture. Instead of establishing a direct connection to the database, he has instructed me to implement an API layer within the view models. This API layer will not only facilitate entity creation but also handle updates and deletions of entities.

To begin, I recognized the need for a new Dto Wrapper that would facilitate the interaction between our application and the API when I was studying the existing code provided by Mr Peter. This wrapper encapsulates the necessary data and functionality required for the saving process. With careful consideration, I designed and implemented the Dto Wrapper to seamlessly integrate with the existing codebase.

Next, I established a new service acting as an interface for API calls. This service handles the communication between our application and the API layer. By abstracting the API interaction into a separate service, a cleaner and more modular code is achieved, improving maintainability and testability. With the groundwork laid, I delved into the entity view model, meticulously analyzing the sections that needed modification to transition it into an API layer. Then, in the view model’s constructor, I initialized the interface services, AutoMapper, and dispatcher, setting the stage for seamless integration with the API layer.

In the case where the user pressed ‘Save’, a dialog is executed. This visually indicates the ongoing progress of the data-saving process, enhancing the user experience. Within this execution, the SaveRoutineAsync method is awaited to ensure the data is saved successfully. Based on the outcome of the saving process, different events are published using the Event Aggregator pattern. If the save operation completes successfully, an event is published with the corresponding parameters, such as the Guid, the mode set to SaveComplete, and an Id was retrieved from the Dto wrapper. 

In addition to the progress mentioned above, I also incorporated the entity’s account details, such as its ID, type, and code. I noticed that this data was also required on the entity’s detailed UI page that I was working on. To address this, I added the account details to the entity profile and ensured that the necessary CRUD operations were implemented at the backend.

Furthermore, I successfully implemented the API functionality, allowing for the correct display and seamless saving and updating of all the data. This accomplishment marked a significant milestone in the integration process for the working entity, as the application was now fully utilizing the power of the API to retrieve and manipulate data effectively.

However, as the week came to a close, I encountered a challenge related to the deletion functionality in the entity’s contact list. It appeared that the deletion process was not functioning as expected. This issue will be my focus for the upcoming week, as I aim to investigate and rectify the problem within the view model. By addressing this issue, I will ensure that the deletion of contacts from the entity’s contact list functions smoothly and seamlessly.

Exploring User Interface (WPF)

Last week, I had the opportunity to explore the user interface of sandbox project. Mr. Peter assigned me a few tasks, one of which was to add a filter to an entity list in the view model, incorporating search functionality and page numbers. As usual, he provided me with a code example of a complete view model to learn from, which was very helpful.

From studying the example view model, I identified several important aspects that I should pay attention to. These include dependency injection, data binding, mapping, working with a DataGrid, and handling events.

Dependency injection, as I mentioned last week, is a crucial concept in the MVVM architecture. It promotes loose coupling, enhances maintainability, and facilitates testing. In the context of the view model, dependency injection involves providing the required dependencies (such as services, data repositories, or other objects) to the view model from an external source, typically through constructor parameters.

The use of a datagrid in the view model suggests that the view presents tabular data or a grid-like structure. A datagrid is a UI control that enables the display and manipulation of tabular data, typically in the form of rows and columns. The view model would provide the necessary data and commands to populate and interact with the datagrid in the view.

Data binding is another essential aspect of MVVM. It establishes a connection between the view and the view model, allowing for seamless synchronization of data changes between the two. With data binding, it bind properties of UI elements in the view to properties in the view model. When the bound properties change in the view model, the corresponding UI elements in the view automatically update, and vice versa.

Mapping is often used in view models to transform and adapt data between different representations. During a method that specifically require mapping, the entities are retrieved from the data source, mapped to view models using AutoMapper, and further processed or filtered as needed. Finally, the view models are assigned as the data source for the view, allowing them to be bound to UI controls and displayed to the user. Since I’m using AutoMapper, I also needed define mapping profiles that specify how properties from a source object should be mapped to properties in a destination object. These profiles can be configured with mapping rules, such as explicitly defining how specific properties should be mapped or specifying custom transformations using lambda expressions.

Lastly, events play a crucial role in MVVM for handling user interactions and notifying the view model of various actions or state changes. Events can be raised in the view when certain user actions occur, such as button clicks or selection changes, and the view model subscribes to these events to perform the appropriate actions or update its internal state accordingly.

Overall, by understanding these concepts and their application in the example view model had assist me in implementing the requested features, that is adding a filter with search functionality and pagination to the entity list in the sand box user interface.

WPF, MVVM and Prism

Last week, I embarked on a task to learn and discover the wonders of WPF (Windows Presentation Foundation), MVVM (Model-View-ViewModel), and Prism. I was thrilled to dive into these concepts, eager to expand my knowledge and enhance my skills. My first instinct was to turn to YouTube, so that I can grab a quick viewpoint of the concept before diving into the details.

I stumbled upon a video that aimed to teach XAML, the declarative markup language used in WPF. The video also touched upon the usage of code-behind, which involves writing code directly in the code-behind file of a XAML-based application. However, Mr. Peter advised focusing on MVVM rather than code-behind because the system we are now utilizing relies heavily on MVVM rather than code-behind. One of the significant reasons why MVVM was used instead was because by utilizing MVVM, we can effectively test the code. On the other hand, if we rely heavily on code-behind, it becomes challenging to isolate and test the code in a systematic manner. Code-behind tightly couples the user interface (View) and the underlying logic, making it difficult to isolate and verify specific functionalities independently. This lack of separation of concerns impedes the ability to write targeted unit tests, as the code-behind files often contain UI-related code that is tightly coupled with the View. 

MVVM stands for Model-View-ViewModel, and it provides a clear separation of concerns, making the codebase more maintainable, testable, and scalable. It promotes a clean architecture that isolates the business logic (ViewModel) from the user interface (View), with the Model representing the data and functionality. By adhering to MVVM principles, we can achieve a modular and extensible codebase. The ViewModel acts as a bridge between the Model and the View, ensuring efficient communication and decoupling of components. This separation is what allows for easier unit testing, as we can test the ViewModel independently of the View. Therefore, adopting MVVM promotes testability by providing a clear separation between the UI and the business logic, facilitating the creation of robust and easily testable code.

Hence, I centred my attention to grasping the skill of properly using XAML and the MVVM pattern effectively. XAML, an XML-based markup language, empowers developers to define user interfaces in a declarative manner, enhancing productivity and fostering a better collaboration between designers and developers. As I delved deeper into XAML, I was fascinated by its versatility. It provided me with a powerful set of tools to create rich and interactive user interfaces, with its support for data binding, styling and much more. Data binding, for example, is what fascinated me the most. In the context of MVVM, data binding allows for automatic updating of UI elements when the underlying data changes, and vice versa. We also don’t need to manually update the UI or handle events to keep it in sync with the data. 

Data binding supports various modes, such as OneWay and TwoWay, providing flexibility in how data flows between the ViewModel and the View. OneWay binding updates the UI when the source property changes, while TwoWay binding allows changes in the UI to propagate back to the source property. By utilizing data binding, we can create dynamic and responsive user interfaces without writing extensive code for manual updates. It simplifies the development process, enhances code maintainability, and promotes a separation of concerns between the UI and the underlying data logic.

While exploring Prism, a framework for building composite applications in WPF and other XAML-based platforms, I was introduced to its modularity and navigation capabilities. Prism embraces the MVVM pattern and offers a range of features that streamline application development, including dependency injection, event aggregation, and region management. It enables the creation of scalable and maintainable applications with ease. 

Throughout this journey, I realised that grasping the fundamental ideas and patterns is like exploring a vast realm of potential. It is not enough to know how to create code or utilise certain tools, it is also necessary to understand the basic principles that form these technologies.

Creating a Get Query for an Entity

For the past few weeks, I’ve been learning and expanding my knowledge of the CQRS pattern. Under the guidance of Mr. Peter, I have been steadily progressing in my understanding of CQRS. This week, my focus was on implementing the final components of the pattern: the “Get by Id” and “Get List” functionalities for an entity.

First, I created the Get List Query Handler class. This class implements the IRequestHandler interface and is responsible for handling the query to retrieve a list of entities. It utilizes the IMapper and a specific service interface. Then, within the Handle method, I first check if the search name provided in the query is null and assign an empty string if necessary. This allows for more flexible search functionality. Next, I call a service to read the paged entity based on the search criteria and pagination details provided in the query.

To prepare the response, I use AutoMapper to map the retrieved list of entities to a list of the entity Dto objects. Additionally, I fetch the total count of entities that match the search criteria to assist with pagination. Finally, I return a PagedDto object containing the count, the mapped list, and the page and size information from the query. 

Moving on to the Get Query By Id Handler class, which handles the query to retrieve a specific entity by its ID. Similar to the previous handler, it implements the IRequestHandler interface and relies on the IMapper and service interfaces. Inside the Handle method, I perform validation using the Get Query Validator. If any validation errors occur, I throw an InvalidOperationException with the corresponding error messages. Otherwise, I proceed to retrieve the entity using the service based on the supplied Id in the query. If an entity is found, I map it to the Dto using AutoMapper and return the result. However, if the entity is not found, I return null to indicate that no entity with the specified ID exists.

To ensure the correctness of my implementation, I have also included a couple of unit tests. These tests verify the success scenarios for both the Read By Id and Read List methods. They utilize a client to simulate HTTP requests and check the returned status codes and data.

In addition to the query handlers and tests, I have also expanded my knowledge by implementing another implementation of the service interface. This interface serves as the abstraction for fetching entities based on various criteria, and I made sure to create the methods in asynchronous form as advised by Mr Peter.

The added methods in the service interface provide the flexibility to retrieve entities by ID, search name, and pagination. For example, the ReadByIdAsync method accepts an ID as a parameter and fetches the corresponding entity asynchronously. It utilizes the underlying data access layer, to retrieve the entity. Similarly, the ReadPagedByAsync method takes parameters such as a search name, page number, and page size to perform a paged retrieval of entities based on the search criteria.

Overall, by implementing these methods in an asynchronous manner, I ensure that the retrieval operations can be performed efficiently and non-blocking. This enables better scalability and responsiveness in the application, especially when dealing with a large number of entities or concurrent requests. Moving forward, my next task involves delving into the UI aspect, where I will embark on learning about WPF, MVVM, and Prism.