This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
# Build entire solution
dotnet build WIDESEAWCS_Server.sln
# Build and run server
cd WIDESEAWCS_Server
dotnet run
# Run tests
cd WIDESEAWCS_Tests
dotnet test
This is a WCS (Warehouse Control System) built with ASP.NET Core 6.0, using:
- Autofac for DI with automatic service discovery via IDependency marker interface
- Quartz.NET for scheduled job execution (device communication loops)
- SqlSugar ORM for database access
- Redis (via WIDESEAWCS_RedisService) for distributed caching with L1+L2 hybrid pattern
- StackExchange.Redis for Redis operations
- TCP Socket Server for real-time device communication
- HslCommunication library for PLC/hardware communication
WIDESEAWCS_Server/ # Main ASP.NET Core API server
WIDESEAWCS_Core/ # Core infrastructure: base classes, DI, extensions, middleware
WIDESEAWCS_Model/ # Data models and DTOs
WIDESEAWCS_Communicator/ # Hardware communication drivers (Siemens, Omron, Modbus, etc.)
WIDESEAWCS_QuartzJob/ # Job scheduling infrastructure and device abstractions
WIDESEAWCS_Tasks/ # Quartz job implementations (device communication loops)
WIDESEAWCS_RedisService/ # Redis services: Cache, Lock, Counter, PubSub, etc.
WIDESEAWCS_*Repository/ # Data access layer implementations
WIDESEAWCS_*Service/ # Business service layer
WIDESEAWCS_Tests/ # Unit tests
Services are automatically registered with Autofac by implementing the empty IDependency marker interface:
// In WIDESEAWCS_Core/IDependency.cs
public interface IDependency { }
// Your service gets auto-registered
public class MyService : IDependency // Automatically registered as scoped
{
// ...
}
Registration happens in AutofacModuleRegister which scans all project assemblies for IDependency implementations.
Important: When adding services to IServiceCollection (e.g., in Program.cs), they can be overridden by Autofac's registrations. Use Remove() to replace existing registrations:
// In RedisServiceSetup.cs - removes MemoryCacheService before adding HybridCacheService
var existing = services.FirstOrDefault(d => d.ServiceType == typeof(ICacheService));
if (existing != null) services.Remove(existing);
The system uses a hybrid L1 (Memory) + L2 (Redis) cache pattern via ICacheService. Three implementations exist:
- MemoryCacheService - Memory only
- RedisCacheService - Redis only
- HybridCacheService - L1+L2 with fallback (default when Redis enabled)
Common methods:
- Add/AddObject - Add cache
- Get/Get<T> - Retrieve cached values
- Remove - Delete single key
- RemoveByPrefix/RemoveByPattern - Bulk delete by pattern
- GetOrAdd<T> - Retrieve or add with factory
- TryAdd/TryUpdate/TryUpdateIfChanged - ConcurrentDictionary-style operations
Configuration in appsettings.json:json "RedisConfig": { "Enabled": true, "ConnectionString": "127.0.0.1:6379,password=P@ssw0rd,...", "KeyPrefix": "wcs:" }
Jobs inherit from JobBase and implement Quartz's IJob:
public class MyDeviceJob : JobBase, IJob
{
public async Task Execute(IJobExecutionContext context)
{
ExecuteJob(context, async () => {
// Job logic here
WriteDebug("MyDevice", "Debug message");
WriteInfo("MyDevice", "Info message");
});
}
}
Jobs are registered dynamically via SchedulerCenterServer using device info from Dt_DeviceInfo table.
Device types:
- IStackerCrane - Stacker cranes
- IConveyorLine - Conveyor lines
- IShuttleCar - Shuttle cars
- IRobot - Robot cranes
Communicator classes wrap the HslCommunication library:
- SiemensS7Communicator / SiemensS7200SmartCommunicator - Siemens PLCs
- OmronEtherNetCommunicator - Omron PLCs
- ModbusTcpCommunicator - Modbus TCP
- SerialPortCommunicator - Serial port devices
The TcpSocketServer (port 2000) handles real-time device communication:
- Managed as a Singleton with SocketServerHostedService
- Client connections stored in ConcurrentDictionary<string, TcpClient>
- Messages handled via OnDataReceived event
Key settings in appsettings.json:
- "urls": "http://*:9292" - Server port
- "QuartzJobAutoStart": true - Auto-start scheduled jobs
- "SocketServer:Enabled": true - Enable TCP server
- "RedisConfig:Enabled": true - Enable Redis caching
- "LogAOPEnable": false - Enable AOP logging
- "DBType": "SqlServer" - Database type
Services follow a layered pattern:
- Interface in WIDESEAWCS_IService/ (e.g., ITaskInfoService)
- Implementation in WIDESEAWCS_Service/ (e.g., TaskInfoService)
- Both implement IDependency for auto-registration
ServiceBase<T, TKey> - Base service with CRUD operationsRepositoryBase<TEntity> - Base repository with SqlSugar ORMApiBaseController - Base API controller with common functionalityJobBase - Base Quartz job with logging helpersI*Service/ and class in *Service/, implement IDependencyJobBase and IJob in WIDESEAWCS_Tasks/WIDESEAWCS_QuartzJob/Device/ and implementConsoleHelper.WriteSuccessLine() / WriteErrorLine() for console output in jobs