Magnus Mårtensson
Microsoft Regional Director, Azure MVP, CEO Loftysoft
Avirag Jain
Director & CTO R Systems
Mahesh Chand
Founder C# Corner, CEO Mindcracker
Chris Gali
CEO & Co-Founder Graphite
Subinder Khurana
Chief Architect StoryProcess, Founder NASSCOM DeepTech Club
Bryan Rishforth
Investor, Chairman Graphite
Bryn Everson
Director Biz Dev Graphite
Raj Tiwari
Digital Transformation Leader, Futurist and Visionary
Joseph Guadagno
Microsoft MVP, Lead Quicken Loans
Nikita Sachdev
Entrepreneur, Blockchain Enthusiast & Advisor, Social Media Influencer
Doug Wagner
COO & Founder Adapt Technical Group
Ritesh Modi
Architect, Senior Evangelist, Cloud Architect
Crystal Wenrick
Director Communications Mindcracker
Allen O’Neill
Microsoft MVP, Consulting Engineer/Architect
Praveen Kumar
CEO MCN Solutions
Chris Love
Founder Love2Dev, Microsoft MVP, Author
Sanjay Vyas
Microsoft Regional Director, Microsoft MVP, Founder & CEO SkillLabs Technologies
Veena Sarda
Deep Learning Consultant, Author
Sekhar Srinivasan
C# Corner MVP, Microsoft Certified Trainer, Pluralsight Author
Lalit Bansal
Founder & CEO - EIY SYS
Navdeep Garg
CEO Revinfotech
Prakash Tripathi
Tech Manager/Leader, Microsoft MVP, Blogger
Bhavna Jain
Breakthrough Consultant
Naveen Sharma
Enterprise Architect, Leadership Coach, Author
Vidya Vrat Agarwal
Principal Architect, Microsoft MVP, Author
Sheetal Agarwal
Founder Clownselors, Medical Clown, Trainer
Abhishek Kant
Founder GTM Catalyst
Vishnu Saran
Founder & CEO VoiceQube
Sandeep Soni
Founder & CEO Deccansoft, Microsoft Certified Trainer
Parveen Malik
AVP InfoSec & Vulnerability Management, Information Security Expert
Nitin Pandit
Microsoft MVP, Developer Evangelist, Author
Niloshima Srivastava
C# Corner MVP, Tech Architect, Trainer, Blogger
Bala Chirtsabesan
Senior Software Engineer at Microsoft, Author
Manoj Mittal
Sr. Technical Architect, C# Corner MVP, Author
Chandni Di
Co-Founder Voice of Slum
Vithal Wadje
Technical Lead, Microsoft MVP, Author
Shivam Ahuja
Founder SkillCircle, Business Mentor
Chervine Bhiwoo
Solution Architect, Microsoft MVP, Author
Saurabh Jain
Vice President Paytm, Founder Fun2Do Labs, Author
Vinay Solanki
Head IoT at Lenovo, Founder IoT-NCR
Anshu kumari
Founder Blockchainkids, Inventor, Trainer
Amit Singal
CEO Startup Buddy
Dev Pratap
Co-Founder & CEO Voice of Slum
Amey Vartak
Technology Consultant, Full Stack Developer, C# Corner MVP, Author
Viswanatha Swamy
Principal Software Engineer, C# Corner MVP, Author
Sanket Verma
Research Engineer @ Ballistics (Forensics) and Chair, PyData Delhi
Sourabh Somani
Lead Developer, Microsoft MVP, Author
Abhishek Mishra
Software Architect, C# Corner MVP, Author
Siddharth Vaghasia
Technical Consultant, C# Corner MVP, Blogger
Bassam Alugili
Senior Software Specialist, Database Expert
S Ravi Kumar
Solution Architect, C# Corner MVP, Author
Sundaram Subramanian
Full Stack Developer, C# Corner MVP, Speaker
Deepesh Somani
Solution Architect, Microsoft MVP, Author
Debasis Saha
Technical Project Manager, C# Corner MVP, Blogger, Author
Vipul Jain
Software Architect, C# Corner MVP, Author
Akshay Patel
Technical Architect, Microsoft Certified Trainer, C# Corner MVP, Author
Stephen Simon
RPA Developer, Evangelist, Author
Vivek Sharma
Founder Kingster636, AR/VR Specialist
Jeetendra Gund
Technical Lead, C# Corner MVP, Author
Sujal Beniwal
AI Enthusiast, Student
M Viknaraj
Microsoft MVP, Azure Architect, Author
Prasham Sabadra
Software Architect, C# Corner MVP, Trainer, Author
Aakash Maurya
Senior Developer, C# Corner MVP, Speaker
Ankit Sharma
Senior Software Engineer, C# Corner MVP, Author
Mangesh Gaherwar
Team Lead, C# Corner MVP, Author
Viral Jain
Technical Consultant, C# Corner MVP, Author
Bhasker Das
Solution Architect, Evangelist
Manish Dwivedi
Associate Project Manager
Ck Nitin
Programmer, Author
Rohit Gupta
Technical Trainer, Author
Manish Tewatia
Full-stack Marketer, UX Designer
Bhavya Gaur
Technical Illustrator
Rohit Tomar
SEO/SMO Expert
Web Track
Cloud & Data Track
Dev Track
Registration & Breakfast
Future of Desktop Apps with JS (ElectronJs)
Nitin Pandit
Building Serverless Microservices Using Microsoft Azure
Vithal Wadje
Innovating RPA: A Robot for Every Person
Stephen Simon
Managing Cloud Storage Accounts using Logic Apps
Viknaraj Manogararajah
Data visualization using Python
Sekhar Srinivasan
Going Cross platform with AR Foundation
Vivek Sharma
Keynote
Managing your Azure dependencies in ASP.NET Core apps using VS
Bala Chirtsabesan
Securing Applications on Intelligent Azure
Abhishek Mishra
Getting started with Blazor the Framework of Future
S Ravi Kumar
Lunch
Build Progressive Web Apps using Angular 9
Debasis Saha
Build and deploy to any platform using Azure DevOps
Chervine Bhiwoo
Deep Dive in Azure Service Bus
Akshay Patel
Build a Native Mobile Application using React Native and JavaScript
Joseph Guadagno
Making sense of Web Job, Web Job SDK and Functions in Azure
Prakash Tripathi
CloudFront Distribution in AWS
Viral Jain
Tea Break
Introduction to PowerBI
Aakash Maurya
Build Advanced SPFx solutions with React and Graph API
Siddharth Vaghasia
Build Business Intelligence Analyst (BIA) Skills
Sundaram Subramanian
Deep dive of Power Platform – AI BUILDER
Prasham Sabadra
Panel 1
What's new in SharePoint development
Vipul Jain
Build a SSO (Single Sign On) based Native JavaScript application with Microsoft Identity within 10 minutes
Manoj Mittal
Panel 2
Applications and working of AI
Veena Sarda
Deploying serverless API's with .Net core 3.0 on AWS & Azure
Amey Vartak
Panel 3
Blockchain with .NET Core (Ark)
Anshu Kumari
Closing Note & Prize Distribution
Dev Track
Cloud Track
Architecture Track
Emerging Tech Track
Registration & Breakfast
Creating Full-Stack Web Apps Using Server-Side Blazor
Ankit Sharma
Real time face recognition with MS Cognitive Services
Niloshima Srivastava
Building Scalable APIs with GraphQL
Jeetendra Gund
Future of development with AI and Blockchain
Navdeep Garg
Debugging Tips and Tricks with Visual Studio 2019
Joseph Guadagno
Azure Containers
Abhishek Kant
Enterprise Architecture
Naveen Sharma
Bot Framework - learn it fast and look like a boss!
Allen O’Neill
Keynote
.Net Core & C# 8 Performance
David McCarter
Working with Azure kubernetes services
Ritesh Modi
Becoming an Architect
Vidyavrat Agarwal
Why Techies Need to Learn Product Management
Saurabh Jain
Lunch
Build a rules engine in .Net Core
Sanjay Vyas
Building CI and CD Pipeline using Azure DevOps
Sandeep Soni
Entity Framework Core - Tips and Tricks, Performance Optimization, and Tuning
Bassam Alugili
Hacking your way into Data Science
Sanket Verma
Speed up your .Net Core Website
Sourabh Somani
Azure
Magnus Mårtensson
Demystifying Open Distro for Elasticsearch
Suman Debnath
Future of Data
Shivam Ahuja
Tea Break
gRPC with C# and .Net Core
Mangesh Gaherwar
Panel 1
Essentials of Cloud security
Parveen Malik
Power platform and Dynamics 365
Deepesh Somani
Microservices - the gRPC Way
Viswanatha Swamy
Panel 2
Reserved
Reserved
Closing Note & Prize Distribution
Building reliable state machine workflows in C#
Modern software often coordinates work that crosses screens, queues, APIs, and human approvals. A claim might be received, checked, approved, rejected, and eventually paid, with each step depending on the result of the previous one. Representing that sequence as a chain of if statements makes valid paths difficult to see and encourages accidental transitions, duplicated business rules, and fragile recovery logic.
A state machine gives those business stages an explicit structure. Each state represents a meaningful point in the workflow, while triggers describe the events that can move it forward. This approach keeps transition rules close to the states they govern and gives developers a clear place to enforce permissions, validation, and organisational policies.
Creating a state machine workflow with the Stateless library in C# is especially useful for .NET applications that need understandable control flow without adopting a large workflow platform. The package provides a lightweight state machine with typed states and triggers, configurable transitions, guards, and support for contextual rules.
The conference programme for C# Corner Annual Conference 2020 explores related areas including C#, Azure, DevOps, data, and application architecture. These subjects suit Australian development teams serving customers who increasingly expect self-service through digital banking, online insurance, and government portals. A well-defined workflow helps maintain consistency across those experiences while keeping critical business decisions auditable.
Defining states, triggers, and outcomes
Start by identifying the stages through which a business transaction can genuinely move. States should describe durable facts rather than temporary UI conditions, so Received may be appropriate while WaitingForSpinner is not. An insurance claim might use states such as Received, UnderReview, Approved, Rejected, Cancelled, and Paid.
Each state also needs a clear set of possible outcomes. Approved might be terminal for one process but transitional for another if payment or settlement follows. Defining that boundary early prevents the state model from hiding missing requirements. It also helps product owners, testers, and operations staff discuss the same workflow using shared terminology.
Triggers represent events that request a transition. They can originate from a user action, a message, a scheduled task, or the result of another service. A typed trigger enum makes invalid commands obvious at compile time and reduces the risk of passing arbitrary strings between application layers.
public enum ClaimStatus
{
Received,
Submitted,
UnderReview,
Approved,
Rejected,
Paid,
Cancelled
}
public enum ClaimTrigger
{
Submit,
StartReview,
Approve,
Reject,
MarkPaid,
Cancel
}
Keep the state and trigger models small enough to understand quickly. If a workflow contains dozens of highly specific states, it may represent several processes that should be separated. Clear boundaries also make it easier to persist a compact state value and identify where an exception occurred.
Making transitions explicit and safe
The Stateless library separates state configuration from the code that drives the workflow. A transition is declared for its source state and trigger, making the accepted path visible without searching through conditional branches. A basic claim workflow can be configured as follows:
var workflow = new StateMachine<ClaimStatus, ClaimTrigger>(ClaimStatus.Received);
workflow.Configure(ClaimStatus.Received)
.Permit(ClaimTrigger.Submit, ClaimStatus.Submitted)
.Permit(ClaimTrigger.Cancel, ClaimStatus.Cancelled);
workflow.Configure(ClaimStatus.Submitted)
.Permit(ClaimTrigger.StartReview, ClaimStatus.UnderReview)
.Permit(ClaimTrigger.Cancel, ClaimStatus.Cancelled);
workflow.Configure(ClaimStatus.UnderReview)
.Permit(ClaimTrigger.Approve, ClaimStatus.Approved)
.Permit(ClaimTrigger.Reject, ClaimStatus.Rejected);
workflow.Fire(ClaimTrigger.Submit);
Unconditional transitions suit deterministic events such as moving a submitted claim into review. Conditional decisions need additional rules. PermitDynamic can select a destination from the current state and supplied context, while guard-style configurations can reject a trigger when a business condition is not satisfied.
Context should carry only the information needed for a decision, such as the claimant identifier, requested amount, acting user, and correlation identifier. Avoid passing an entire entity into the state machine because it couples workflow rules to persistence and increases the amount of sensitive data moving through the transition layer.
A transition should change workflow state; it should not quietly perform every downstream action. Database updates, emails, queue publishing, and payment requests are easier to coordinate when they happen around the transition under explicit policies. This separation preserves the readability of the state model and leaves room for retries and compensation.
Designing resilient transitions around external work
Real workflows interact with systems that can be slow or temporarily unavailable. A transition might approve a claim in the state machine while a message broker rejects the publication of an event, or a payment provider may time out after accepting a request. The workflow must therefore distinguish a completed state change from an unsuccessful side effect.
Use an idempotency key derived from the transition and business entity. Retrying the same command should return the known result rather than approve, charge, or notify twice. Where an event must eventually reach another service, store it in an outbox within the same database transaction as the state change. A background publisher can then deliver the event safely and mark it as processed.
Australian organisations in mining, logistics, healthcare, and financial services often connect workflows to partner systems with different availability guarantees. These environments reward bounded retries, sensible timeouts, and dead-letter handling. A transition that depends on several services should not leave the claim in an ambiguous intermediate state merely because one dependency failed.
Recovery rules should reflect the business meaning of each state. A rejected payment might leave an approved claim awaiting another attempt, while a failed notification should not reverse an approved claim. Model retries separately from business transitions, and record enough information to explain whether the state changed, the external action failed, or the operation remains uncertain.
For long-running processes, persist the current state before beginning the next external action. The Stateless library does not replace durable workflow storage, so the surrounding application must save and reload state when required. Timestamps should be stored in UTC, while any displayed Australian local time should be calculated at the presentation boundary.
Integrating the workflow into a C# application
Keep the state machine inside an application service rather than embedding it directly in controllers or UI components. The service can expose methods such as SubmitClaim, ApproveClaim, and CancelClaim, each of which loads the current state, validates the caller, performs the transition, and coordinates persistence. This creates one consistent entry point for web, API, worker, and message-driven callers.
Dependency injection suits this design because the workflow service can receive repositories, clocks, identity providers, and messaging abstractions without depending directly on infrastructure. An in-memory implementation remains useful for unit tests, while production code can use SQL Server, PostgreSQL, or another durable store through the repository layer.
Persistence requires attention to concurrency. Two reviewers might attempt to process the same claim simultaneously, so the application should use optimistic concurrency with a version column or another suitable conflict control. If the stored state no longer matches the state used to calculate a transition, reload it and decide explicitly whether the command remains valid.
Many Australian development teams are distributed across Sydney, Melbourne, and Brisbane, with workloads hosted in nearby Azure regions. This geographic spread makes observable transitions, stable correlation identifiers, and recoverable processing important. Logs should identify the workflow, entity, previous state, requested trigger, and resulting state without exposing sensitive customer information.
Testing and observing stateful behaviour
Test the transition matrix rather than only the happy path. For each state, verify every accepted trigger, its resulting state, and the rejection of unsupported commands. Guard tests should cover missing permissions, incorrect amounts, expired approvals, and other conditions that can realistically affect Australian businesses.
Keep external dependencies behind interfaces and replace them with deterministic fakes during state-machine tests. A test can then prove that an invalid transition causes no repository update or message publication. Integration tests can separately verify how the application stores a state, handles a database conflict, and resumes after a worker restart.
Operational visibility should show both current state and recent transitions. Structured logs, metrics, and tracing can reveal whether claims remain in review too long, which transitions fail repeatedly, and whether workers are processing events promptly. Dashboards should aggregate operational signals without reproducing personal or financial details.
Privacy obligations shape what may be logged and retained. Organisations handling personal information generally need to consider the Privacy Act 1988 and the Australian Privacy Principles, including security, transparency, and data minimisation. A state identifier can usually support investigation with less exposure than a complete claim payload, provided it is not combined with unnecessary customer data.
A practical adoption checklist
Adopt state machines incrementally by selecting one bounded process with clear states, a small number of triggers, and meaningful business rules. The first implementation should demonstrate value without turning the application into a custom workflow engine. As confidence grows, shared infrastructure can support richer patterns.
Choose the durability approach according to the process rather than the novelty of the design. Short calculations may need nothing beyond memory, whereas payments, claims, and regulated approvals often require persistence, audit history, and safe restart behaviour. The following practices provide a dependable foundation:
- Give every state a precise business meaning and document terminal states.
- Declare transitions close to the state configuration instead of scattering them through conditionals.
- Pass typed context containing only the data required for transition decisions.
- Separate state changes from external side effects and make retryable actions idempotent.
- Persist state, version information, and an audit trail for long-running workflows.
- Test valid transitions, rejected triggers, concurrency conflicts, and recovery paths.
| Approach | State storage | Durability and recovery | Strongest fit | Main trade-off |
|---|---|---|---|---|
| Stateless library in process | Application memory | Lost when the process exits | Short, single-process workflows | Simple and fast, but not durable |
| Stateless library with application storage | Database or repository | Restored by the application | Claims, orders, and approvals | Requires custom persistence and concurrency handling |
| Durable workflow engine | Engine-managed | Designed for pause, retry, and resume | Long-running multi-service processes | Greater operational complexity |
| General-purpose orchestrator | Workflow definitions and runtime | Depends on the selected runtime | Broad integration and routing | Less direct fit for a focused domain model |
1, CBD, Maharaj Surajmal Road, Near Yamuna Sports Complex, Delhi, 110032
GENERAL QUERIES
Manish Tewatia
manish@csharpcon.com
+91-9718-431-042
TICKET QUERIES
Atul Gupta
conference@csharpcon.com
+91-9910-125-804