The Roslyn Effect

image courtesy – https://blogs.starcio.com/2017/02/can-ai-learn-to-code.html

Coding in the Age of Generative AI

Let us do something different this time. We start with a code and will fill you in on what we wanted to talk
about.
namespace DataCollector.Model.View;

partial class TopicViewModel {

public string Topic { get; set;}
public string DataFragment {get;set;}

}
We have a simple POCO, i.e., Plain Old CLR Object. You could relate it to POJO (Plain Old Java Object) if
you have a Java background. In an MAUI application, this view model has to bind to a UI. Notifying the
change in property aids in 2-way binding and is a foundational pillar to any MAUI application code. The
interface INotifyPropertyChanged is responsible for managing the notification of the change and is a
standard in any XAML codebase. Though, there is nothing limiting you to use it elsewhere. Developers
typically consider writing code that implements INotifyPropertyChanged as boilerplate code.
namespace DataCollector.Model.View;

partial class TopicViewModel: INotifyPropertyChanged {

public event PropertyChangedEventHandler PropertyChanged;

private string _topic;
public string Topic {
get { return _topic; }
set {
_topic = value;
PropertyChanged(this, new PropertyChangedEventArgs(nameof(Topic)));
}
}

private string _dataFragment;
public string DataFragment {
get { return _dataFragment; }
set {
_dataFragment = value;
PropertyChanged(this, new PropertyChangedEventArgs(nameof(DataFragment)));
}
}

}
In your career, you would certainly have come across such sections of code which you have to repeat with
subtle changes. Over the years language designers have leaps of progress in reducing boilerplate code.
However, there is always room to improve. Isn’t it? Generative AI in recent times has come and covered
and overtook years of progress in moments. Without picking on the deep topic of Generative AI and talking
about how it works, let us first look at how it worked earlier. If you were surprised by the use of past tense.
Wonder no more. Generating code was of interest to many since the dawn of programming. Before you get
carried away let us emphasize; by “Generating” we do not mean intelligent code generated from English.
We use the word “Generating” literally to mean writing code which is in our case driven by rule. The
approach for the ages has been semantic-driven. So, the rule in the generation activity understands the
language nuances and inspects the existing code not as plain text but by understanding the code within the
language structures. If you have come across the library Fody or have dived deep into the realms of
reflection in .NET you would strike resonance with us immediately. The compiler SDK in C# is called
Roslyn. That reveals the API required to understand and capitalize the semantics of the C# language. Fody
as a library has also evolved to offer a variant where it uses something called Source Generators.
using Microsoft.CodeAnalysis;

namespace SourceGenerator.PropertyChange;

[Generator]
public class ImplementINotifyPropertyChange : ISourceGenerator {

public void Execute(GeneratorExecutionContext context) {

}

public void Initialize(GeneratorInitializationContext context) {

}
}

This is a scaffolding of the Source Generator. One would have to introduce inspection and generation logic
to typically; the Execute method of the class. However, complex code generation might need code in the
Initialize method too. Before we dive with interest into the generator’s logic, let us first share some keeping
suggestions to keep the IDE happy with what we are doing.
The first one of few is that the Source Generator must be added to a separate project than to the project
where it is expected to operate. The project must target the .NET Standard 2.0. If you are a developer who
likes to do the plumbing by themselves while learning the trade, here is how the project file should look
<Project Sdk=”Microsoft.NET.Sdk”>

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include=”Microsoft.CodeAnalysis.CSharp” Version=”4.6.0” PrivateAssets=”all” />
<PackageReference Include=”Microsoft.CodeAnalysis.Analyzers” Version=”3.3.4” PrivateAssets=”all”
/>
</ItemGroup>

</Project>
If you are wondering how this project then work on the MAUI project which carries those many ViewModels
which have to be wired. There is no magic or convention (yet). The best part is you have to add the Source
Generator project as a reference. Instead of fiddling with Build Events. Build Events are for different
purposes and are typically used in the DevOps style of work. In the MAUI project add a fragment like this –
<ItemGroup>
<ProjectReference Include = “[Path To SourceGeneratorProject.csproj]” OutputItemType=”Analyzer”
ReferenceOutputAssembly=”false” />
</ItemGroup>
If you use Visual Studio, please do not “add reference” to a project. Instead at present hand weave this to
the MAUI project. Once this is in place, whenever you build the MAUI project
ImplementINotifyPropertyChange.Executed will be called in by the C# compiler. The best part of Source
Generators is it will drop in the file to the folder so that you could inspect it and if required latter modify it.
This is the best part which eases the maintenance burden. If you are glued watch for the next dispatch on
this topic to pick on the Execute method.