The Dark Arts of Self-Writing Code: A Journey from DOS to .NET Sorcery

The Dark Arts of Self-Writing Code: A Journey from DOS to .NET Sorcery

The Beginning of a Digital Sorcerer

Every master of the dark arts has an origin story, and mine begins in the ancient realm of MS-DOS 6.1. What started as simple experimentation with BAT files would eventually lead me down a path to discovering one of programming’s most powerful arts: metaprogramming.

I still remember the day my older brother Oscar introduced me to the mystical DIR command. He was three years ahead of me in school, already initiated into the computer classes that would begin in “tercer ciclo” (7th through 9th grade) in El Salvador. This simple command, capable of revealing the contents of directories, was my first spell in what would become a lifelong pursuit of programming magic.

My childhood hobbies – playing video games, guitar, and piano (a family tradition, given my father’s musical lineage) – faded into the background as I discovered the enchanting world of DOS commands. The discovery that files ending in .exe were executable spells and .com files were commands that accepted parameters opened up a new realm of possibilities.

Armed with EDIT.COM, a primitive but powerful text editor, I began experimenting with every file I could find. The real breakthrough came when I discovered AUTOEXEC.BAT, a mystical scroll that controlled the DOS startup ritual. This was my first encounter with automated script execution, though I didn’t know it at the time.

The Path of Many Languages

My journey through the programming arts led me through many schools of magic: Turbo Pascal, C++, Fox Pro (more of an application framework than a pure language), Delphi, VB6, VBA, VB.NET, and finally, my true calling: C#.

During my university years, I co-founded my first company with my cousin “Carlitos,” supported by my uncle Carlos Melgar, who had been like a father to me. While we had some coding experience, our ambition to create our own ERP system led us to expand our circle. This is where I met Abel, one of two programmers we recruited who were dating my cousins at the time. Abel, coming from a Delphi background, introduced me to a concept that would change my understanding of programming forever: reflection.

Understanding the Dark Arts of Metaprogramming

What Abel revealed to me that day was just the beginning of my journey into metaprogramming, a form of magic that allows code to examine and modify itself at runtime. In the .NET realm, this sorcery primarily manifests through reflection, a power that would have seemed impossible in my DOS days.

Let me share with you the secrets I’ve learned along this path:

The Power of Reflection: Your First Spell

// A basic spell of introspection
Type stringType = typeof(string);
MethodInfo[] methods = stringType.GetMethods();
foreach (var method in methods)
{
    Console.WriteLine($"Discovered spell: {method.Name}");
}

This simple incantation allows your code to examine itself, revealing the methods hidden within any type. But this is just the beginning.

Conjuring Objects from the Void

As your powers grow, you’ll learn to create objects dynamically:

public class ObjectConjurer
{
    public T SummonAndEnchant<T>(Dictionary<string, object> properties) where T : new()
    {
        T instance = new T();
        Type type = typeof(T);
        
        foreach (var property in properties)
        {
            PropertyInfo prop = type.GetProperty(property.Key);
            if (prop != null && prop.CanWrite)
            {
                prop.SetValue(instance, property.Value);
            }
        }
        return instance;
    }
}

Advanced Rituals: Expression Trees

Expression<Func<int, bool>> ageCheck = age => age >= 18;
var parameter = Expression.Parameter(typeof(int), "age");
var constant = Expression.Constant(18, typeof(int));
var comparison = Expression.GreaterThanOrEqual(parameter, constant);
var lambda = Expression.Lambda<Func<int, bool>>(comparison, parameter);

The Price of Power: Security and Performance

Like any powerful magic, these arts come with risks and costs. Through my journey, I learned the importance of protective wards:

Guarding Against Dark Forces

// A protective ward for your reflective operations
[SecurityPermission(SecurityAction.Demand, ControlEvidence = true)]
public class SecretKeeper
{
    private readonly string _arcaneSecret = "xyz";
    
    public string RevealSecret(string authToken)
    {
        if (ValidateToken(authToken))
            return _arcaneSecret;
        throw new ForbiddenMagicException("Unauthorized attempt to access secrets");
    }
}

The Cost of Power

Ritual Type Energy Cost (ms) Mana Usage
Direct Cast 1 Baseline
Reflection 10-20 2x-3x
Cached Cast 2-3 1.5x
Compiled 1.2-1.5 1.2x

To mitigate these costs, I learned to cache my spells:

public class SpellCache
{
    private static readonly ConcurrentDictionary<string, MethodInfo> SpellBook 
        = new ConcurrentDictionary<string, MethodInfo>();

    public static MethodInfo GetSpell(Type type, string spellName)
    {
        string key = $"{type.FullName}.{spellName}";
        return SpellBook.GetOrAdd(key, _ => type.GetMethod(spellName));
    }
}

Practical Applications in the Modern Age

Today, these dark arts power many of our most powerful frameworks:

  • Entity Framework uses reflection for its magical object-relational mapping
  • Dependency Injection containers use it to automatically wire up our applications
  • Serialization libraries use it to transform objects into different forms
  • Unit testing frameworks use it to create test doubles and verify behavior

Wisdom for the Aspiring Sorcerer

From my journey from DOS batch files to the heights of .NET metaprogramming, I’ve gathered these pieces of wisdom:

  1. Cache your incantations whenever possible
  2. Guard your secrets with proper wards
  3. Measure the cost of your rituals
  4. Use direct casting when available
  5. Document your dark arts thoroughly

Conclusion

Looking back at my journey from those first DOS commands to mastering the dark arts of metaprogramming, I’m reminded that every programmer’s path is unique. That young boy who first typed DIR in MS-DOS could never have imagined where that path would lead. Today, as I work with advanced concepts like reflection and metaprogramming in .NET, I’m reminded that our field is one of continuous learning and evolution.

The dark arts of metaprogramming may be powerful, but like any tool, their true value lies in knowing when and how to use them effectively. Remember, while the ability to make code write itself might seem like sorcery, the real magic lies in understanding the fundamentals and growing from them. Whether you’re starting with basic commands like I did or diving straight into advanced concepts, every step of the journey contributes to your growth as a developer.

And who knows? Maybe one day you’ll find yourself teaching these dark arts to the next generation of digital sorcerers.

The Dark Magic of .NET: Exploring Harmony Library in 2025

The Dark Magic of .NET: Exploring Harmony Library in 2025

As the new year (2025) starts, I want to share some insights from my role at Xari. While Javier and I founded the company together (he’s the Chief in Command, and I’ve dubbed myself the Minister of Dark Magic), our rapid growth has made these playful titles more meaningful than we expected.

Among my self-imposed responsibilities are:

  • Providing ancient knowledge to the team (I’ve been coding since MS-DOS 6.1 – you do the math!)
  • Testing emerging technologies
  • Deciphering how and why our systems work
  • Achieving the “impossible” (even if impractical, we love proving it can be done)

Our Technical Landscape

As a .NET shop, we develop everything from LOB applications to AI-powered object detection systems and mainframe database connectors. Our preference for C# isn’t just about the language – it’s about the power of the .NET ecosystem itself.

.NET’s architecture, with its intermediate language and JIT compilation, opens up fascinating possibilities for code manipulation. This brings us to one of my favorite features: Reflection, or more broadly, metaprogramming.

Enter Harmony: The Art of Runtime Magic

Harmony is a powerful library that transforms how we approach runtime method patching in .NET applications. Think of it as a sophisticated Swiss Army knife for metaprogramming. But why would you need it?

Real-World Applications

1. Performance Monitoring


[HarmonyPatch(typeof(CriticalService), "ProcessData")]
class PerformancePatch
{
    static void Prefix(out Stopwatch __state)
    {
        __state = Stopwatch.StartNew();
    }
    
    static void Postfix(Stopwatch __state)
    {
        Console.WriteLine($"Processing took {__state.ElapsedMilliseconds}ms");
    }
}
        

2. Feature Toggling in Legacy Systems


[HarmonyPatch(typeof(LegacySystem), "SaveToDatabase")]
class ModernizationPatch
{
    static bool Prefix(object data)
    {
        if (FeatureFlags.UseNewStorage)
        {
            ModernDbContext.Save(data);
            return false; // Skip old implementation
        }
        return true;
    }
}
        

The Three Pillars of Harmony

Harmony offers three powerful ways to modify code:

1. Prefix Patches

  • Execute before the original method
  • Perfect for validation
  • Can prevent original method execution
  • Modify input parameters

2. Postfix Patches

  • Run after the original method
  • Ideal for logging
  • Can modify return values
  • Access to execution state

3. Transpilers

  • Modify the IL code directly
  • Most powerful but complex
  • Direct instruction manipulation
  • Used for advanced scenarios

Practical Example: Method Timing

Here’s a real-world example we use at Xari for performance monitoring:


[HarmonyPatch(typeof(Controller), "ProcessRequest")]
class MonitoringPatch
{
    static void Prefix(out Stopwatch __state)
    {
        __state = Stopwatch.StartNew();
    }

    static void Postfix(MethodBase __originalMethod, Stopwatch __state)
    {
        __state.Stop();
        Logger.Log($"{__originalMethod.Name} execution: {__state.ElapsedMilliseconds}ms");
    }
}
        

When to Use Harmony

Harmony shines when you need to:

  • Modify third-party code without source access
  • Implement system-wide logging or monitoring
  • Create modding frameworks
  • Add features to sealed classes
  • Test legacy systems

The Dark Side of Power

While Harmony is powerful, use it wisely:

  • Avoid in production-critical systems where stability is paramount
  • Consider simpler alternatives first
  • Be cautious with high-performance scenarios
  • Document your patches thoroughly

Conclusion

In our work at Xari, Harmony has proven invaluable for solving seemingly impossible problems. While it might seem like “dark magic,” it’s really about understanding and leveraging the powerful features of .NET’s architecture.

Remember: with great power comes great responsibility. Use Harmony when it makes sense, but always consider simpler alternatives first. Happy coding!

 

Exploring .NET 9’s Sequential GUIDs: A Game-Changer for XAF/XPO Developers

Exploring .NET 9’s Sequential GUIDs: A Game-Changer for XAF/XPO Developers

While researching useful features in .NET 9 that could benefit XAF/XPO developers, I discovered something particularly interesting: Version 7 GUIDs (RFC 9562 specification). These new GUIDs offer a crucial feature – they’re sortable.

This discovery brought me back to an issue I encountered two years ago while working on the SyncFramework. We faced a peculiar problem where Deltas were correctly generated but processed in the wrong order in production environments. The occurrences seemed random, and no clear pattern emerged. Initially, I thought using Delta primary keys (GUIDs) to sort the Deltas would ensure they were processed in their generation order. However, this assumption proved incorrect. Through testing, I discovered that GUID generation couldn’t be trusted to be sequential. This issue affected multiple components of the SyncFramework. Whether generating GUIDs in C# or at the database level, there was no guarantee of sequential ordering. Different database engines could sort GUIDs differently. To address this, I implemented a sequence service as a solution.Enter .NET 9 with its Version 7 GUIDs (conforming to RFC 9562 specification). These new GUIDs are genuinely sequential, making them reliable for sorting operations.

To demonstrate this improvement, I created a test solution for XAF with a custom base object. The key implementation occurs in the OnSaving method:


protected override void OnSaving()
{
    base.OnSaving();
    if (!(Session is NestedUnitOfWork) && Session.IsNewObject(this) && oid.Equals(Guid.Empty))
    {
        oid = Guid.CreateVersion7();
    }
}
        

Notice the use of CreateVersion7() instead of the traditional NewGuid(). For comparison, I also created another domain object using the traditional GUID generation:


protected override void OnSaving()
{
    base.OnSaving();
    if (!(Session is NestedUnitOfWork) && Session.IsNewObject(this) && oid.Equals(Guid.Empty))
    {
        oid = Guid.NewGuid();
    }
}
        

When creating multiple instances of the traditional GUID domain object, you’ll notice that the greater the time interval between instance creation, the less likely the GUIDs will maintain sequential ordering.

GUID Version 7

 

GUID Old Version

This new feature in .NET 9 could significantly simplify scenarios where sequential ordering is crucial, eliminating the need for additional sequence services in many cases. Here is the repo on GitHubHappy coding until next time!

Related article

On my GUID, common problems using GUID identifiers | Joche Ojeda

 

Using DevExpress Chat Component and Semantic Kernel ResponseFormat to show a product carousel

Using DevExpress Chat Component and Semantic Kernel ResponseFormat to show a product carousel

Today, when I woke up, it was sunny but really cold, and the weather forecast said that snow was expected.

So, I decided to order ramen and do a “Saturday at home” type of project. My tools of choice for this experiment are:

1) DevExpress Chat Component for Blazor

I’m thrilled they have this component. I once wrote my own chat component, and it’s a challenging task, especially given the variety of use cases.

2) Semantic Kernel

I’ve been experimenting with Semantic Kernel for a while now, and let me tell you—it’s a fantastic tool if you’re in the .NET ecosystem. It’s so cool to have native C# code to interact with AI services in a flexible way, making your code mostly agnostic to the AI provider—like a WCF for AIs.

Goal of the Experiment

The goal for today’s experiment is to render a list of products as a carousel within a chat conversation.

Configuration

To accomplish this, I’ll use prompt execution settings in Semantic Kernel to ensure that the response from the LLM is always in JSON format as a string.

var Settings = new OpenAIPromptExecutionSettings 
{ 
    MaxTokens = 500, 
    Temperature = 0.5, 
    ResponseFormat = "json_object" 
};

The key part here is the response format. The chat completion can respond in two ways:

  • Text: A simple text answer.
  • JSON Object: This format always returns a JSON object, with the structure provided as part of the prompt.

With this approach, we can deserialize the LLM’s response to an object that helps conditionally render the message content within the DevExpress Chat Component.

Structure

Here’s the structure I’m using:

public class MessageData
{
    public string Message { get; set; }
    public List Options { get; set; }
    public string MessageTemplateName { get; set; }
}

public class OptionSet
{
    public string Name { get; set; }
    public string Description { get; set; }
    public List Options { get; set; }
}

public class Option
{
    public string Image { get; set; }
    public string Url { get; set; }
    public string Description { get; set; }
};
  • MessageData: This structure will always be returned by our LLM.
  • Option: A list of options for a message, which also serves as data for possible responses.
  • OptionSet: A list of possible responses to feed into the prompt execution settings.

Prompt Execution Settings

One more step on the Semantic Kernel side is configuring the prompt execution settings:

var Settings = new OpenAIPromptExecutionSettings 
{ 
    MaxTokens = 500, 
    Temperature = 0.5, 
    ResponseFormat = "json_object" 
};

Settings.ChatSystemPrompt = $"You need to answer using this JSON format with this structure {Structure} " +
                            $"Before giving an answer, check if it exists within this list of option sets {OptionSets}. " +
                            $"If your answer does not include options, the message template value should be 'Message'; otherwise, it should be 'Options'.";

In the prompt, we specify the structure {Structure} we want as a response, provide a list of possible options for the message in the {OptionSets} variable, and add a final line to guide the LLM on which template type to use.

Example Requests and Responses

For example, when executing the following request:

  • Prompt: “Show me a list of Halloween costumes for cats.”

We’ll get this response from the LLM:

{
    "Message": "Please select one of the Halloween costumes for cats",
    "Options": [
        {"Image": "./images/catblack.png", "Url": "https://cat.com/black", "Description": "Black cat costume"},
        {"Image": "./images/catwhite.png", "Url": "https://cat.com/white", "Description": "White cat costume"},
        {"Image": "./images/catorange.png", "Url": "https://cat.com/orange", "Description": "Orange cat costume"}
    ],
    "MessageTemplateName": "Options"
}

With this JSON structure, we can conditionally render messages in the chat component as follows:

<DxAIChat CssClass="my-chat" MessageSent="MessageSent">
    <MessageTemplate>
        <div>
            @{
                if (@context.Typing)
                {
                    <span>Loading...</span>
                }
                else
                {
                    MessageData md = null;
                    try
                    {
                        md = JsonSerializer.Deserialize<MessageData>(context.Content);
                    }
                    catch
                    {
                        md = null;
                    }
                    if (md == null)
                    {
                        <div class="my-chat-content">
                            @context.Content
                        </div>
                    }
                    else
                    {
                        if (md.MessageTemplateName == "Options")
                        {
                            <div class="centered-carousel">
                                <Carousel class="carousel-container" Width="280" IsFade="true">
                                    @foreach (var option in md.Options)
                                    {
                                        <CarouselItem>
                                            <ChildContent>
                                                <div>
                                                    <img src="@option.Image" alt="demo-image" />
                                                    <Button Color="Color.Primary" class="carousel-button">@option.Description</Button>
                                                </div>
                                            </ChildContent>
                                        </CarouselItem>
                                    }
                                </Carousel>
                            </div>
                        }
                        else if (md.MessageTemplateName == "Message")
                        {
                            <div class="my-chat-content">
                                @md.Message
                            </div>
                        }
                    }
                }
            }
        </div>
    </MessageTemplate>
</DxAIChat>

End Solution Example

Here’s an example of the final solution:

You can find the full source code here: https://github.com/egarim/devexpress-ai-chat-samples and a short video here https://youtu.be/dxMnOWbe3KA

 

Async Code Execution in XAF Actions

Async Code Execution in XAF Actions

Lately, I’ve been working extensively on interacting with LLMs using the Semantic Kernel framework. My experiments usually start as NUnit test projects, where I prototype my ideas.

Once an experiment is successful, I move it to XAF. Recently, I faced challenges with executing asynchronous code and updating the XAF UI. This process is tricky because some solutions might appear to work but fail under certain conditions.

Goals

Here’s what I aim to achieve:

  1. Execute asynchronous code within the execute handler of an action.
  2. Notify the UI and access the current view, object, and object space.
  3. Run multiple operations on a background thread.

For more background, check out these links on async executions within XAF actions:

WebForms

Blazor

Complete source code for this test can be found on GitHub.

Common Cases

1. Blocking the UI Thread (this will not work)

If you don’t make your action async, attempting to get the awaiter will block the UI thread, freezing your application.


ActionBlockUIThread = new SimpleAction(this, nameof(ActionBlockUIThread), "View");
ActionBlockUIThread.Execute += ActionBlockUIThread_Execute;

protected virtual void ActionBlockUIThread_Execute(object sender, SimpleActionExecuteEventArgs e) {
    var Tasks = GetTaskList();
    StringBuilder Results = new StringBuilder();
    foreach (var item in Tasks) {
        Results.AppendLine(item.Invoke().GetAwaiter().GetResult().ToString());
    }
    MessageOptions options = new MessageOptions { Duration = 2000, Message = Results.ToString(), Type = InformationType.Success };
    Application.ShowViewStrategy.ShowMessage(options);
}

2. Using Async Modifier (somehow works)

Marking your handler as async prevents blocking but keeps the UI responsive, which can allow the user to modify or navigate away from the current view, causing exceptions.


protected virtual async void ActionWithAsyncModifier_Execute(object sender, SimpleActionExecuteEventArgs e) {
    var Tasks = GetTaskList();
    StringBuilder Results = new StringBuilder();
    foreach (var item in Tasks) {
        var CurrentResult = await item.Invoke();
        Results.AppendLine(CurrentResult.ToString());
    }
    MessageOptions options = new MessageOptions { Duration = 2000, Message = Results.ToString(), Type = InformationType.Success };
    Application.ShowViewStrategy.ShowMessage(options);
}

A slightly modified Blazor version of this code also illustrates similar issues.

Executing Object Space Operations Inside Async Action, things that can happen

This approach still leaves the UI responsive, risking disposal of object space if the user navigates away, if that happens you will end up with an exception


protected virtual async void ActionWithAsyncModifierAndOsOperations_Execute(object sender, SimpleActionExecuteEventArgs e) {
    var Instance = GetInstance();
    var Tasks = GetTaskList();
    StringBuilder Results = new StringBuilder();
    foreach (var item in Tasks) {
        var CurrentResult = await item.Invoke();
        Results.AppendLine(CurrentResult.ToString());
    }
    Instance.Result = Results.ToString();
    ViewCommit();
    MessageOptions options = new MessageOptions { Duration = 3000, Message = Instance.Result, Type = InformationType.Success };
    Application.ShowViewStrategy.ShowMessage(options);
}

Proposed Solution

My solution utilizes a background worker to handle async operations while locking the UI thread with a loading indicator. This allows us to react to progress on the UI thread.

Async Background Worker Example

Here’s how the AsyncBackgroundWorker is set up and used:


protected virtual void AsyncActionWithAsyncBackgroundWorker_Execute(object sender, SimpleActionExecuteEventArgs e) {
    var tasks = GetTaskList();
    var worker = new AsyncBackgroundWorker

Handling Background Worker Events


protected virtual void ProcessingDone(Dictionary<int, object> results) {
    // Interact with UI and object space
}

protected virtual void OnReportProgress(int progress, string status, object result) {
    MessageOptions options = new MessageOptions { Duration = 2000, Message = status, Type = InformationType.Success };
    Application.ShowViewStrategy.ShowMessage(options);
}

Blazor Implementation

The Blazor version manages UI locking by showing a loading indicator and reporting progress through the UI thread:

source here: https://github.com/egarim/XafAsyncActions/blob/master/XafAsyncActions.Blazor.Server/Controllers/MyViewControllerBlazor.cs


protected async override void AsyncActionWithAsyncBackgroundWorker_Execute(object sender, SimpleActionExecuteEventArgs e) {
    loading.Hold("Loading");
    base.AsyncActionWithAsyncBackgroundWorker_Execute(sender, e);
}

protected async override void ProcessingDone(Dictionary<int, object> results) {
    base.ProcessingDone(results);
    loading.Release("Loading");
}

When you run this implementation, it will look like this

As you can see the task are being run on the background worker and every time a task is finish is reported back to the U.I thread where we can execute a notification (this is actually optional)

When all the tasks are finished, I hide the loading indicator, and the user can interact with the view again

I hope this article clarifies async execution in XAF. I will update the repository as new scenarios arise.