Design Smart Parking System for Multi layer Buildings in C#

Flexible and Scalable Architecture to Optimize Parking Management ๐Ÿš—๐Ÿ๏ธ๐Ÿšš

DotNet Full Stack Dev
4 min readDec 4, 2024

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, and Truck.
  • 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!

--

--

DotNet Full Stack Dev
DotNet Full Stack Dev

Written by DotNet Full Stack Dev

Join me to master .NET Full Stack Development & boost your skills by 1% daily with insights, examples, and techniques! https://dotnet-fullstack-dev.blogspot.com

No responses yet