0

I've written an Assembler, Interpreter, and Disassembler for MIPS.

They're split each into their own projects, with a base project containing some basic models to use between each.

One of those models is an Instruction struct. I would like to add a DebugDisplayAttribute to this struct that uses the disassembler to display the instruction.

I don't want these components to be co-dependent in a release build, so I do need them to be separate projects. However, in a debug build I would like to include the disassembler in the base for this DebugDisplayAttribute

Ideally, I'd simply make the disassembler conditionally referenced by the base project to include in debug builds, however since the disassembler depends on the assembler, and both the disassembler and assembler depend on the base project, this introduces a cycling dependency.

Is there some way to add an attribute to a struct from a different project? Some way to make the projects co-build in this respect? Some better solution entirely? Or do I need to write a bunch of conditionally compiling dependency injection code for this (which would be weird because then the service has to be set before it can be used).

2
  • 1
    Maybe it would be easier with a full debugger visualizer (learn.microsoft.com/en-us/visualstudio/extensibility/…) as another (vs extension) project, using same source files linked from existing projects, but w/o dependency restrictions. Commented Jun 23 at 5:57
  • @SimonMourier This looks like kind of a lot of work, but almost certainly the best approach. Thanks for the resource! Commented Jun 28 at 1:46

1 Answer 1

0

for debug purposes I could have used static class to link project without introducing circular dependencies:

#region Base Library

[System.Diagnostics.DebuggerDisplay("{Preview}")]
public class Instruction
{
    public int A;
    public int B;
    
    #if DEBUG
    public string Preview => DebugHelper.Decompile(this);
    #endif
}

    #if DEBUG

    public abstract class DebugDecompiler
    {
        public abstract string Decompile(Instruction x);
    }

    public static class DebugHelper
    {
        public static DebugDecompiler Decompiler { get; set; }

        public static string Decompile(Instruction x) => Decompiler?.Decompile(x) ?? x.ToString();
    }

    #endif

#endregion Base Library

and then initialized it from entry point of another project:

#region Disassembler library

using System;
                    
public class Program
{
    public static void Main()
    {
        var x = new Instruction { A = 2, B = 3 };
        
        #if DEBUG
        DebugHelper.Decompiler = new DebugDecompilerImplementation();
        
        Console.WriteLine(x.Preview);
        #endif
    }
}

    #if DEBUG
    
    public class DebugDecompilerImplementation : DebugDecompiler
    {
        public override string Decompile(Instruction x) => $"{x.A} + {x.B}";
    }
    
    #endif

#endregion
Sign up to request clarification or add additional context in comments.

2 Comments

Yeah, so this is basically the dependency injection solution. The biggest issue with this is that the disassembler is still a library, so the question becomes where to put the injection. As I have it currently, each application using the library has to do the injection itself, which kind of sucks.
maybe it will work if DebugHelper dynamically loads disassembler dll, and necessary types from it

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.