I have started working on my budget app. I am using this app as an opportunity to learn Angular, especially how it connects with .NET Core.
You can see the overall purpose on this app on my projects page. Basically I want an app to handle the electronic portion of my family’s budget process, which I currently do with spreadsheets. The physical portion of our process will not change.
There is one new requirement I have come up with since I wrote that page. There should be 2 types of monthly expenses, ones that accumulate and ones that don’t.
As an example, let’s say I have 2 categories, eating out and fuel. I want to put $200 in eating out every month no matter what. But I want $200 max in fuel each month.
Now let’s say I have a month where I only spend $175 in each category. The extra $25 in eating out would roll over, giving me $225 for the next month. However, fuel would be allocated $175 for the month to bring the total to $200, giving me that extra $25 to shift to a different category.
Here is the frequency enum I will be using:
public enum FrequencyType : byte { OneTime = 1, MonthlyCumulative, MonthlySet, Quarterly, Yearly }
These cover everything I need at this point.
The next step is to start building the code infrastructure. Here is the structure I use in my code:
- Solution
- Business Folder
- Business Projects
- Data Folder
- Data Projects
- Interactive Folder
- Interactive Projects
- Tests Folder
- Tests Projects
This structure helps keep my mind focused on what I am working on at any given moment. If I am in a project in the Interactive folder, for example, I know I am working on an interface of some kind. It might be web based, WPF based, or console based but it involves user interaction. If the code I am writing is business logic, I know I am probably putting it in the wrong place.
The last thing I want to mention is the direction I will be going with the business layer in the app. I have used the Repository pattern in the past. It has always felt lacking in several areas. I recently came across a couple articles by Steven van Deursen covering the command–query separation pattern. I really like how it has simplified my coding, especially on the testing side.
Here are the interfaces I will be using for queries:
public interface IQuery<TResult> { } public interface IQueryHandler<TQuery, TResult> where TQuery : IQuery<TResult> { TResult Handle(TQuery query); }
And here are the interfaces for commands:
public enum CommandResult { Ok, Error } public interface ICommandResult { CommandResult Result { get; } ICollection<string> Messages { get; } } public interface ICommandHandler<TCommand> { Task<ICommandResult> Handle(TCommand command); }
You will notice one change from Steven’s code. I added a ICommandResult so the commands can return results to the user. While it can be nice to be able to fire and forget a command, I have found this impractical in practice. The user will want to be notified of the result of a command, especially if there was an error. ICommandResult allows me to notify the UI if there was an error so it can display the messages to the user.
In my next post I will be adding a category list to the Angular app. This will allow the user to see all the current categories. I will also be adding the functionality for the user to add a category.
You can check out the current state of this app on GitHub.