Design Smart Parking System for Multi layer Buildings in C#
Flexible and Scalable Architecture to Optimize Parking Management ๐๐๏ธ๐
Managing parking in a multi layer building can be challenging, especially when you need to handle various types of vehicles like cars, bikes, and trucks. From allocating slots to calculating charges, the system must be robust, scalable, and easy to maintain.
In this blog, weโll explore a high-level design for a parking system using C#. The architecture is tailored for flexibility, supporting multiple vehicle types, dynamic slot allocation, and efficient billing. Letโs dive into the key components and their implementation.
๐Explore more at: https://dotnet-fullstack-dev.blogspot.com/
๐ Clapping would be appreciated! ๐
Key Features of the Parking System
Support for Multiple Vehicle Types:
- Handle diverse vehicles like cars, bikes, and trucks with specific slot requirements.
Dynamic Slot Allocation:
- Allocate parking slots dynamically based on availability and vehicle type.
Billing and Pricing:
- Calculate parking charges based on time and vehicle category.
Entry and Exit Management:
- Issue parking tickets and manage slot availability upon vehicle entry and exit.
Extensibility:
- Easily add new vehicle types, layers, or advanced features like online payments.
High-Level Architecture
The system is broken into modular components for better maintainability and scalability. Below are the key components and their responsibilities:
1. Models (Entities)
- Vehicle: Abstract representation of any vehicle, with specific types like
Car
,Bike
, andTruck
. - ParkingSlot: Represents individual parking slots in layers.
- ParkingLayer: Groups multiple slots into a logical layer.
- Ticket: Tracks vehicle entry and exit, slot usage, and charges.
2. Services
- Slot Allocation Service: Handles finding and freeing parking slots.
- Billing Service: Calculates charges based on parking duration and vehicle type.
3. Controllers
- Parking Controller: Acts as the entry and exit point, orchestrating ticket generation, billing, and slot management.
Step-by-Step Implementation in C#
Step 1: Define Base Classes and Models
The system starts with abstracting vehicles and defining slots and layers.
public abstract class Vehicle
{
public string LicensePlate { get; set; }
public DateTime EntryTime { get; set; }
public abstract string VehicleType { get; }
}
public class Car : Vehicle
{
public override string VehicleType => "Car";
}
public class Bike : Vehicle
{
public override string VehicleType => "Bike";
}
public class Truck : Vehicle
{
public override string VehicleType => "Truck";
}
public class ParkingSlot
{
public int SlotId { get; set; }
public bool IsOccupied { get; set; }
public string AllowedVehicleType { get; set; }
public Vehicle ParkedVehicle { get; set; }
}
public class ParkingLayer
{
public int LayerId { get; set; }
public List<ParkingSlot> Slots { get; set; } = new List<ParkingSlot>();
}
public class Ticket
{
public int TicketId { get; set; }
public string LicensePlate { get; set; }
public int SlotId { get; set; }
public int LayerId { get; set; }
public DateTime EntryTime { get; set; }
public DateTime? ExitTime { get; set; }
public decimal? Charges { get; set; }
}
Step 2: Slot Allocation Logic
The Slot Allocation Service ensures slots are dynamically assigned and freed based on vehicle type and availability.
public class SlotAllocationService
{
private List<ParkingLayer> _layers;
public SlotAllocationService(List<ParkingLayer> layers)
{
_layers = layers;
}
public (int layerId, int slotId) AllocateSlot(Vehicle vehicle)
{
foreach (var layer in _layers)
{
var availableSlot = layer.Slots.FirstOrDefault(slot =>
!slot.IsOccupied && slot.AllowedVehicleType == vehicle.VehicleType);
if (availableSlot != null)
{
availableSlot.IsOccupied = true;
availableSlot.ParkedVehicle = vehicle;
return (layer.LayerId, availableSlot.SlotId);
}
}
throw new Exception("No available slots for this vehicle type.");
}
public void FreeSlot(int layerId, int slotId)
{
var layer = _layers.FirstOrDefault(l => l.LayerId == layerId);
var slot = layer?.Slots.FirstOrDefault(s => s.SlotId == slotId);
if (slot != null)
{
slot.IsOccupied = false;
slot.ParkedVehicle = null;
}
}
}
Step 3: Billing Logic
The Billing Service calculates charges based on the vehicle type and duration of parking.
public class BillingService
{
private readonly Dictionary<string, decimal> _hourlyRates = new()
{
{ "Car", 10 },
{ "Bike", 5 },
{ "Truck", 20 }
};
public decimal CalculateCharges(string vehicleType, DateTime entryTime, DateTime exitTime)
{
var hours = (exitTime - entryTime).TotalHours;
return Math.Ceiling(hours) * _hourlyRates[vehicleType];
}
}
Step 4: Entry and Exit Management
The Parking Controller orchestrates vehicle entry and exit.
public class ParkingController
{
private SlotAllocationService _slotAllocationService;
private BillingService _billingService;
private List<Ticket> _tickets = new();
public ParkingController(SlotAllocationService slotAllocationService, BillingService billingService)
{
_slotAllocationService = slotAllocationService;
_billingService = billingService;
}
public Ticket EnterParking(Vehicle vehicle)
{
var (layerId, slotId) = _slotAllocationService.AllocateSlot(vehicle);
var ticket = new Ticket
{
TicketId = _tickets.Count + 1,
LicensePlate = vehicle.LicensePlate,
LayerId = layerId,
SlotId = slotId,
EntryTime = DateTime.Now
};
_tickets.Add(ticket);
return ticket;
}
public Ticket ExitParking(int ticketId)
{
var ticket = _tickets.FirstOrDefault(t => t.TicketId == ticketId);
if (ticket == null) throw new Exception("Invalid ticket.");
ticket.ExitTime = DateTime.Now;
ticket.Charges = _billingService.CalculateCharges(
ticket.LicensePlate, ticket.EntryTime, ticket.ExitTime.Value);
_slotAllocationService.FreeSlot(ticket.LayerId, ticket.SlotId);
return ticket;
}
}
Advanced Features for Extensibility
Real-Time Slot Availability:
- Provide APIs to check available slots in real time.
Online Payments:
- Integrate with payment gateways for seamless billing.
Notifications:
- Notify users of available slots or billing details via SMS or email.
Conclusion
The architecture outlined above demonstrates how a parking system can handle multiple vehicle types in a multi layer building using C#. By modularization the components into services, models, and controllers, the system becomes highly maintainable and extensible. Whether you want to add new features or scale to more layers and vehicles, this design provides a robust foundation.
With this smart parking system, you can easily manage parking complexities, enhance customer experience, and ensure efficient space utilization.
Designing is never one-size-fits-all; unique systems come from unique minds. Share your thoughts and suggestions โ weโd love to hear them!