Proprietary Methods for Isolating Critical Business Logic in Multi-Layered Architectures
David Shergilashvili
Enterprise Architect & Software Engineering Leader | Cloud-Native, AI/ML & DevOps Expert | Driving Blockchain & Emerging Tech Innovation | Future CTO
Introduction
In modern enterprise applications, protecting core business logic is crucial for maintaining competitive advantage and ensuring system security. This article provides practical, implementable approaches to isolating critical business logic, with complete working examples.
Core Concepts and Implementation
1. Basic Business Logic Isolation
Let's start with a complete, working example of basic business logic isolation:
using System;
using System.Collections.Generic;
// Basic business entities
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public decimal BasePrice { get; set; }
}
public class Order
{
public int Id { get; set; }
public List<OrderItem> Items { get; set; } = new List<OrderItem>();
public DateTime OrderDate { get; set; }
public string CustomerId { get; set; }
}
public class OrderItem
{
public int ProductId { get; set; }
public int Quantity { get; set; }
public decimal UnitPrice { get; set; }
}
// Isolated business logic implementation
public sealed class PricingEngine
{
// Private constructor prevents instantiation outside the class
private PricingEngine() { }
// Singleton instance with lazy initialization
private static readonly Lazy<PricingEngine> _instance =
new Lazy<PricingEngine>(() => new PricingEngine());
public static PricingEngine Instance => _instance.Value;
// Internal calculation methods are private
private decimal CalculateBaseTotal(List<OrderItem> items)
{
decimal total = 0;
foreach (var item in items)
{
total += item.Quantity * item.UnitPrice;
}
return total;
}
private decimal ApplyVolumeDiscount(decimal total, int totalItems)
{
if (totalItems >= 10)
return total * 0.95m; // 5% discount
if (totalItems >= 5)
return total * 0.97m; // 3% discount
return total;
}
// Public method with controlled access to internal logic
public decimal CalculateFinalPrice(Order order)
{
try
{
// Input validation
if (order == null)
throw new ArgumentNullException(nameof(order));
if (order.Items == null || order.Items.Count == 0)
throw new ArgumentException("Order must contain items");
// Calculate total items
int totalItems = 0;
foreach (var item in order.Items)
{
totalItems += item.Quantity;
}
// Apply business rules
decimal baseTotal = CalculateBaseTotal(order.Items);
decimal afterDiscount = ApplyVolumeDiscount(baseTotal, totalItems);
return Math.Round(afterDiscount, 2);
}
catch (Exception ex)
{
// Log the error (in a real application)
Console.WriteLine($"Error in price calculation: {ex.Message}");
throw;
}
}
}
// Example of using the isolated business logic
public class OrderProcessor
{
public decimal ProcessOrder(Order order)
{
// Access the pricing engine through its controlled interface
var finalPrice = PricingEngine.Instance.CalculateFinalPrice(order);
return finalPrice;
}
}
2. Enhanced Protection with Encryption
Here's a complete example of protecting sensitive business rules using encryption:
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
public class SecureBusinessRules
{
private static readonly byte[] Key = new byte[32]
{
// Example key - in production, this would be securely stored
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10,
0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20
};
private static readonly byte[] Iv = new byte[16]
{
0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30
};
private readonly Dictionary<string, string> _encryptedRules;
public SecureBusinessRules()
{
_encryptedRules = new Dictionary<string, string>
{
// Pre-encrypted business rules
{"PricingRule", EncryptRule("BasePrice * 1.2")},
{"DiscountRule", EncryptRule("Quantity >= 10 ? 0.15 : 0.0")}
};
}
private string EncryptRule(string rule)
{
using (Aes aes = Aes.Create())
{
aes.Key = Key;
aes.IV = Iv;
using (MemoryStream msEncrypt = new MemoryStream())
{
using (ICryptoTransform encryptor = aes.CreateEncryptor())
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
{
swEncrypt.Write(rule);
}
return Convert.ToBase64String(msEncrypt.ToArray());
}
}
}
private string DecryptRule(string encryptedRule)
{
byte[] cipherText = Convert.FromBase64String(encryptedRule);
using (Aes aes = Aes.Create())
{
aes.Key = Key;
aes.IV = Iv;
using (MemoryStream msDecrypt = new MemoryStream(cipherText))
using (ICryptoTransform decryptor = aes.CreateDecryptor())
using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
using (StreamReader srDecrypt = new StreamReader(csDecrypt))
{
return srDecrypt.ReadToEnd();
}
}
}
public string GetRule(string ruleName)
{
if (!_encryptedRules.ContainsKey(ruleName))
throw new ArgumentException($"Rule '{ruleName}' not found");
return DecryptRule(_encryptedRules[ruleName]);
}
}
领英推荐
3. Monitoring and Auditing
Here's a practical implementation of business logic monitoring:
using System;
using System.Collections.Concurrent;
using System.Threading.Tasks;
public class BusinessOperationMonitor
{
private readonly ConcurrentDictionary<string, OperationMetrics> _metrics =
new ConcurrentDictionary<string, OperationMetrics>();
public class OperationMetrics
{
public int ExecutionCount { get; set; }
public TimeSpan TotalExecutionTime { get; set; }
public DateTime LastExecutionTime { get; set; }
public int ErrorCount { get; set; }
}
public async Task<T> MonitorOperation<T>(string operationName, Func<Task<T>> operation)
{
var metrics = _metrics.GetOrAdd(operationName, _ => new OperationMetrics());
var startTime = DateTime.UtcNow;
try
{
var result = await operation();
// Update success metrics
UpdateMetrics(metrics, startTime);
return result;
}
catch (Exception)
{
// Update failure metrics
metrics.ErrorCount++;
throw;
}
}
private void UpdateMetrics(OperationMetrics metrics, DateTime startTime)
{
var executionTime = DateTime.UtcNow - startTime;
metrics.ExecutionCount++;
metrics.TotalExecutionTime += executionTime;
metrics.LastExecutionTime = DateTime.UtcNow;
}
public OperationMetrics GetMetrics(string operationName)
{
return _metrics.GetOrAdd(operationName, _ => new OperationMetrics());
}
}
Using These Components Together
Here's how to use all these components in a real application:
public class OrderSystem
{
private readonly BusinessOperationMonitor _monitor = new BusinessOperationMonitor();
private readonly SecureBusinessRules _rules = new SecureBusinessRules();
public async Task<decimal> ProcessOrderWithMonitoring(Order order)
{
return await _monitor.MonitorOperation("OrderProcessing", async () =>
{
// Get the pricing rule
string pricingRule = _rules.GetRule("PricingRule");
// Use the pricing engine
var processor = new OrderProcessor();
decimal finalPrice = processor.ProcessOrder(order);
// Additional processing as needed
await Task.Delay(100); // Simulate some async work
return finalPrice;
});
}
}
Best Practices for Implementation
Conclusion
This article provides complete, working examples of business logic isolation techniques. You can directly use these implementations in your applications and modify them as needed. Remember that while these examples are functional, you would need to add additional security measures and proper configuration management in a production environment.