diff --git a/internalUsages/Pure.Domain/Class1.cs b/internalUsages/Pure.Domain/Class1.cs
index f577d2f2..310b6d65 100644
--- a/internalUsages/Pure.Domain/Class1.cs
+++ b/internalUsages/Pure.Domain/Class1.cs
@@ -1,7 +1,6 @@
 using Pure.Domain.Generated;
 using ResultBoxes;
 using Sekiban.Pure;
-using Sekiban.Pure.Exception;
 namespace Pure.Domain;
 
 public record UnconfirmedUser(string Name, string Email) : IAggregatePayload;
@@ -136,40 +135,40 @@ public void Test1()
 //             command.Handle);
 // }
 // now writing manually, but it will be generated by the source generator
-public class DomainEventTypes : IEventTypes
-{
-    public ResultBox<IEvent> GenerateTypedEvent(
-        IEventPayload payload,
-        PartitionKeys partitionKeys,
-        string sortableUniqueId,
-        int version) => payload switch
-    {
-        UserRegistered userRegistered => new Event<UserRegistered>(
-            userRegistered,
-            partitionKeys,
-            sortableUniqueId,
-            version),
-        UserConfirmed userConfirmed => new Event<UserConfirmed>(
-            userConfirmed,
-            partitionKeys,
-            sortableUniqueId,
-            version),
-        UserUnconfirmed userUnconfirmed => new Event<UserUnconfirmed>(
-            userUnconfirmed,
-            partitionKeys,
-            sortableUniqueId,
-            version),
-        BranchCreated branchCreated => new Event<BranchCreated>(
-            branchCreated,
-            partitionKeys,
-            sortableUniqueId,
-            version),
-        BranchNameChanged branchNameChanged => new Event<BranchNameChanged>(
-            branchNameChanged,
-            partitionKeys,
-            sortableUniqueId,
-            version),
-        _ => ResultBox<IEvent>.FromException(
-            new SekibanEventTypeNotFoundException($"Event Type {payload.GetType().Name} Not Found"))
-    };
-}
+// public class DomainEventTypes : IEventTypes
+// {
+//     public ResultBox<IEvent> GenerateTypedEvent(
+//         IEventPayload payload,
+//         PartitionKeys partitionKeys,
+//         string sortableUniqueId,
+//         int version) => payload switch
+//     {
+//         UserRegistered userRegistered => new Event<UserRegistered>(
+//             userRegistered,
+//             partitionKeys,
+//             sortableUniqueId,
+//             version),
+//         UserConfirmed userConfirmed => new Event<UserConfirmed>(
+//             userConfirmed,
+//             partitionKeys,
+//             sortableUniqueId,
+//             version),
+//         UserUnconfirmed userUnconfirmed => new Event<UserUnconfirmed>(
+//             userUnconfirmed,
+//             partitionKeys,
+//             sortableUniqueId,
+//             version),
+//         BranchCreated branchCreated => new Event<BranchCreated>(
+//             branchCreated,
+//             partitionKeys,
+//             sortableUniqueId,
+//             version),
+//         BranchNameChanged branchNameChanged => new Event<BranchNameChanged>(
+//             branchNameChanged,
+//             partitionKeys,
+//             sortableUniqueId,
+//             version),
+//         _ => ResultBox<IEvent>.FromException(
+//             new SekibanEventTypeNotFoundException($"Event Type {payload.GetType().Name} Not Found"))
+//     };
+// }
diff --git a/src/Sekiban.Pure.SourceGenerator/Class1.cs b/src/Sekiban.Pure.SourceGenerator/CommandExecutionExtensionGenerator.cs
similarity index 99%
rename from src/Sekiban.Pure.SourceGenerator/Class1.cs
rename to src/Sekiban.Pure.SourceGenerator/CommandExecutionExtensionGenerator.cs
index 5120b6b9..aa12a442 100644
--- a/src/Sekiban.Pure.SourceGenerator/Class1.cs
+++ b/src/Sekiban.Pure.SourceGenerator/CommandExecutionExtensionGenerator.cs
@@ -1,4 +1,4 @@
-using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis;
 using Microsoft.CodeAnalysis.CSharp.Syntax;
 using Microsoft.CodeAnalysis.Text;
 using System.Collections.Immutable;
@@ -6,9 +6,6 @@
 using System.Text;
 namespace Sekiban.Pure.SourceGenerator;
 
-public class Class1
-{
-}
 [Generator]
 public class CommandExecutionExtensionGenerator : IIncrementalGenerator
 {
diff --git a/src/Sekiban.Pure.SourceGenerator/EventTypesGenerator.cs b/src/Sekiban.Pure.SourceGenerator/EventTypesGenerator.cs
new file mode 100644
index 00000000..fed85079
--- /dev/null
+++ b/src/Sekiban.Pure.SourceGenerator/EventTypesGenerator.cs
@@ -0,0 +1,121 @@
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+using Microsoft.CodeAnalysis.Text;
+using System.Collections.Immutable;
+using System.Linq;
+using System.Text;
+namespace Sekiban.Pure.SourceGenerator;
+
+[Generator]
+public class EventTypesGenerator : IIncrementalGenerator
+{
+    public void Initialize(IncrementalGeneratorInitializationContext context)
+    {
+        // Collect all class and record declarations
+        var typeDeclarations = context
+            .SyntaxProvider
+            .CreateSyntaxProvider(
+                static (node, _) => node is ClassDeclarationSyntax || node is RecordDeclarationSyntax,
+                static (ctx, _) => ctx.Node)
+            .Where(static typeDecl => typeDecl is ClassDeclarationSyntax || typeDecl is RecordDeclarationSyntax);
+
+        // Combine with compilation information
+        var compilationAndTypes = context.CompilationProvider.Combine(typeDeclarations.Collect());
+
+
+        // Generate source code
+        context.RegisterSourceOutput(
+            compilationAndTypes,
+            (ctx, source) =>
+            {
+                var (compilation, types) = source;
+                var commandTypes = ImmutableArray.CreateBuilder<CommandWithHandlerValues>();
+
+                commandTypes.AddRange(GetEventValues(compilation, types));
+
+                // Generate source code
+                var rootNamespace = compilation.AssemblyName;
+                var sourceCode = GenerateSourceCode(commandTypes.ToImmutable(), rootNamespace);
+                ctx.AddSource("EventTypes.g.cs", SourceText.From(sourceCode, Encoding.UTF8));
+            });
+
+    }
+    public ImmutableArray<CommandWithHandlerValues> GetEventValues(
+        Compilation compilation,
+        ImmutableArray<SyntaxNode> types)
+    {
+        var iEventPayloadSymbol = compilation.GetTypeByMetadataName("Sekiban.Pure.IEventPayload");
+        if (iEventPayloadSymbol == null)
+            return new ImmutableArray<CommandWithHandlerValues>();
+        var eventTypes = ImmutableArray.CreateBuilder<CommandWithHandlerValues>();
+        foreach (var typeSyntax in types)
+        {
+            var model = compilation.GetSemanticModel(typeSyntax.SyntaxTree);
+            var typeSymbol = model.GetDeclaredSymbol(typeSyntax) as INamedTypeSymbol;
+            var allInterfaces = typeSymbol.AllInterfaces.ToList();
+            if (typeSymbol != null && typeSymbol.AllInterfaces.Any(m => m == iEventPayloadSymbol))
+            {
+                var interfaceImplementation = typeSymbol.AllInterfaces.First(m => m == iEventPayloadSymbol);
+                eventTypes.Add(
+                    new CommandWithHandlerValues
+                    {
+                        InterfaceName = interfaceImplementation.Name,
+                        RecordName = typeSymbol.ToDisplayString()
+                    });
+            }
+        }
+        return eventTypes.ToImmutable();
+    }
+
+    private string GenerateSourceCode(ImmutableArray<CommandWithHandlerValues> eventTypes, string rootNamespace)
+    {
+        var sb = new StringBuilder();
+        sb.AppendLine("// Auto-generated by IncrementalGenerator");
+        sb.AppendLine("using System.Threading.Tasks;");
+        sb.AppendLine("using ResultBoxes;");
+        sb.AppendLine("using Sekiban.Pure;");
+        sb.AppendLine("using Sekiban.Pure.Exception;");
+
+        sb.AppendLine();
+        sb.AppendLine($"namespace {rootNamespace}.Generated");
+        sb.AppendLine("{");
+        sb.AppendLine($"    public class {rootNamespace.Replace(".", "")}EventTypes : IEventTypes");
+        sb.AppendLine("    {");
+        sb.AppendLine("        public ResultBox<IEvent> GenerateTypedEvent(");
+        sb.AppendLine("            IEventPayload payload,");
+        sb.AppendLine("            PartitionKeys partitionKeys,");
+        sb.AppendLine("            string sortableUniqueId,");
+        sb.AppendLine("            int version) => payload switch");
+        sb.AppendLine("        {");
+
+        foreach (var type in eventTypes)
+        {
+            switch (type.InterfaceName, type.TypeCount)
+            {
+                case ("IEventPayload", 0):
+                    sb.AppendLine(
+                        $"            {type.RecordName} {type.RecordName.Split('.').Last().ToLower()} => new Event<{type.RecordName}>(");
+                    sb.AppendLine($"                {type.RecordName.Split('.').Last().ToLower()},");
+                    sb.AppendLine("                partitionKeys,");
+                    sb.AppendLine("                sortableUniqueId,");
+                    sb.AppendLine("                version),");
+                    break;
+            }
+        }
+
+        sb.AppendLine("            _ => ResultBox<IEvent>.FromException(");
+        sb.AppendLine(
+            "                new SekibanEventTypeNotFoundException($\"Event Type {payload.GetType().Name} Not Found\"))");
+        sb.AppendLine("        };");
+        sb.AppendLine("    };");
+        sb.AppendLine("}");
+
+        return sb.ToString();
+    }
+    public class CommandWithHandlerValues
+    {
+        public string InterfaceName { get; set; }
+        public string RecordName { get; set; }
+        public int TypeCount { get; set; }
+    }
+}
\ No newline at end of file
diff --git a/tests/Pure.Domain.Test/UnitTest1.cs b/tests/Pure.Domain.Test/UnitTest1.cs
index 67cc9520..effc0c9f 100644
--- a/tests/Pure.Domain.Test/UnitTest1.cs
+++ b/tests/Pure.Domain.Test/UnitTest1.cs
@@ -32,7 +32,7 @@ public void TenantPartitionKeysTest()
     public async Task SimpleEventSourcing()
     {
         Repository.Events.Clear();
-        var executor = new CommandExecutor { EventTypes = new DomainEventTypes() };
+        var executor = new CommandExecutor { EventTypes = new PureDomainEventTypes() };
 
         Assert.Empty(Repository.Events);
         await executor.Execute(new RegisterBranch("branch1"));
@@ -83,7 +83,7 @@ public async Task SimpleEventSourcing()
     public async Task SimpleEventSourcingFunction()
     {
         Repository.Events.Clear();
-        var executor = new CommandExecutor { EventTypes = new DomainEventTypes() };
+        var executor = new CommandExecutor { EventTypes = new PureDomainEventTypes() };
 
         Assert.Empty(Repository.Events);
         var registerBranch = new RegisterBranch("branch1");
@@ -168,7 +168,7 @@ await executor.ExecuteFunction(
     public async Task ChangeBranchNameSpec()
     {
         Repository.Events.Clear();
-        var executor = new CommandExecutor { EventTypes = new DomainEventTypes() };
+        var executor = new CommandExecutor { EventTypes = new PureDomainEventTypes() };
 
         Assert.Empty(Repository.Events);
         var executed = await executor.Execute(new RegisterBranch("branch1"));
@@ -204,7 +204,7 @@ public void CanUseDelegateSpec()
     public async Task MultipleBranchesSpec()
     {
         Repository.Events.Clear();
-        var executor = new CommandExecutor { EventTypes = new DomainEventTypes() };
+        var executor = new CommandExecutor { EventTypes = new PureDomainEventTypes() };
 
         Assert.Empty(Repository.Events);
         var executed = await executor.Execute(new RegisterBranch("branch 0"));
@@ -234,7 +234,7 @@ public async Task MultipleBranchesSpec()
     public async Task ICommandAndICommandWithAggregateRestrictionShouldWorkWithFunctionTest()
     {
         Repository.Events.Clear();
-        var executor = new CommandExecutor { EventTypes = new DomainEventTypes() };
+        var executor = new CommandExecutor { EventTypes = new PureDomainEventTypes() };
 
         var command1 = new RegisterBranch2("aaa");
         var result = await executor.ExecuteFunction(