A Casual Password Manager App With A Non Casual Styles

Alperen Yalçn
5 min readJan 23, 2024

Why did I start to write a password manager app while there are tons of apps exist in the market. One of the good parts of being software engineer is you can build your own stuff when you dont trust a technology.

The application has limited functionality for the first version. It simply performs CRUD operations for passwords. Before getting details I want to show some screenshots from app to show you what it looks like.

Screenshots from application

Let’s take a look under the hood. As you guessed app is written in Flutter and I used bloc state management with freezed because I guess it feels a little bit easier. Also implemented DDD (domain driven design) architecture to make it more complex and i will explain in the following paragraph. Some packages I used in the app:

 password_strength_checker: ^1.2.2    # password strength checks 
flutter_secure_storage: ^8.0.0 # storing password in a secure way
localstorage: ^4.0.1+4
app_bar_with_search_switch: ^1.5.4
flutter_bloc: ^8.1.3 # state management
dartz: ^0.10.1 # functional programming support
auto_route: ^5.0.1 # simplified routing mechanism
freezed_annotation: ^2.2.0
injectable: ^2.1.1
get_it: ^7.6.0

Domain Driven Design

Taken From ResoCoder Youtube Channel

Domain Layer

In implementing DDD architecture with Flutter, the first step involves creating a robust domain layer that encapsulates the core business logic and entity classes. In this project I’ve implemented an ApplicationModel to streamline the transfer of password data, ensuring a structured and efficient flow. I’ve also created a StorageFailure class, designed specifically for handling errors in a more user-friendly way.

Infrastructure Layer

I typically prefer to develop this layer after the domain layer since it relies on the structures and logic established in the domain layer. This layer primarily focuses on repositories and services. Before beginning the implementation, it’s essential to identify the required functions for the application. Subsequently, I create an abstract class, which serves as a blueprint. Then, I inherit from this abstract class to create a repository class. Additionally, I implemented dependency injection, which I will explain on later in the process.

Repository and Service classes

Presentation Layer

This layer is likely the most familiar, as it is purely Flutter-based. I choose to create this layer before the application layer because it allows us to define and visualize the requirements of our application layer. In this phase, we focus on building the user interface and Flutter widgets.

Folder Structure in Presentation Layer

Application Layer

The Application Layer, also known as the heart of the application, is where all the layers come together, especially when using the bloc package for state management. Here, events triggered in the user interface lead to the execution of predefined functions. As a result, the application goes through state changes, updating the user interface accordingly. I have multiple bloc folders and each of them has its own resposibilities. You can see one of them below.

Also,if you notice that I use the dartz package, which allows Dart to incorporate functional programming concepts. This helps in writing cleaner and more expressive code. Dartz introduces functional types like Either ,Option and Fold contributing to a more organized and maintainable codebase. The use of Either, for instance, promotes better error handling by explicitly representing either a success or a failure, reducing the likelihood of unexpected issues.

Dependency Injection (DI)

Dependency injection is a software design pattern that focuses on providing components, usually classes or services, with their dependencies from external sources rather than creating them internally. This promotes a more flexible and modular code structure, making it easier to manage and maintain.

GetIt is a popular DI library in the Dart and Flutter ecosystem. It serves as a dependency injection container, allowing developers to register and retrieve instances of services throughout their application.

Injectable package is a code generation-based dependency injection library built on top of GetIt for Dart and Flutter applications. Its primary goal is to streamline and simplify the DI process by automating the generation of service registrations, reducing the need for manual configuration.

After some technical knowledge lets take a lot how I used those knowledges in the app. First of all I defined a function which you can see below. A global variable named getIt is defined as the instance of the GetIt container, serving as a centralized location for managing various dependencies and services throughout the application. The configureDependencies function initializes the GetIt container using the generated $initGetIt function, automatically handling the registration of dependencies. Additionally, it is crucial to include a call to the configureDependencies() function within the main function before invoking the runApp() function to ensure the proper initialization of dependencies.

Final Words

We covered all parts of the application. At first, it seemed easy, but as we went through each section, it turned out to be more detailed than expected. I plan to improve the app by adding new features and enhancing the design.

Here is the link to the code repository.

I hope you learned something today, happy coding 👊.

--

--