Proprietary Methods for Isolating Critical Business Logic in Multi-Layered Architectures

Proprietary Methods for Isolating Critical Business Logic in Multi-Layered Architectures

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

  1. Always validate inputs before processing
  2. Use encryption for sensitive business rules
  3. Implement comprehensive monitoring
  4. Keep the core business logic in sealed classes
  5. Use private constructors and static factories where appropriate
  6. Implement proper exception handling and logging

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.

要查看或添加评论,请登录

David Shergilashvili的更多文章

社区洞察

其他会员也浏览了