Looking over the Managed StrongName code for today's post, I've become dissatisfied with several things in the current code base, and I think that a bit of refactoring is in store for this project before its next addition. One of the major things is the way that the code is split between the StrongNames.Native.dll and msn.exe modules at this point. The initial goal of this project was to show examples of how to use the various StrongName APIs from managed code, and msn.exe was simply a sample demonstrating each of the APIs. The real meat of the work was meant to be in the library, which turned out to be just a bunch of P/Invoke declarations. That's not very useful ... especially considering that the format of almost every command is:
ModeHandler -> Managed Wrapper -> P/Invoke
Meaning that each command usually parses its arguments then passes them on to a nice managed wrapper for the various APIs. And anyone who would ever want to use the APIs would need to write similar wrapper code. It seems rather silly to me that this code is in the msn.exe module, instead if in the library where other callers could use it.
So step number one will be to move the wrappers, which make up a sort of managed StrongName API, into the dll with the P/Invoke methods. Of course, that makes the name StrongName.Native.dll incorrect, so I'll be moving the root namespace to MS.StrongName, and renaming the library MS.StrongName.dll. The goal here will be for msn.exe to contain nothing more than command line parsing, and I/O tasks. It should be a very thin wrapper around the functionality exposed by the library.
Another thing that bothers me about the current design is that I have all the P/Invokes categorized and split into different classes. While this worked out at first, some of the methods can belong to more than one "category" .... for instance today's example of StrongNameTokenFromAssemblyEx, which belongs to both "extraction" and "tokens." In order to fix this, I'm going to get rid of the Native namespace, and move all of the P/Invoke declarations into a NativeMethods class. Categorization still makes sense for the managed API, since any function there that is multi-purpose is easily split into two.
Finally, various other cleanup can be done at the same time. For instance:
- Mode was never really a good choice for the name of the way msn works after passing it a flag. I'll rename this to Command.
- Instead of using resources.GetString(), I'll take advantage of the new resgen feature to generate C# classes from input files
- Speaking of resources ... since all of my resources are strings, I'll switch from .resx to the .txt format
- Instead of scattering calls to Console.WriteLine and Console.Error.WriteLine everywhere, it would be nicer to have a centralized class to handle interaction with the user.
I don't have an ETA on this work, but it will be before the next Managed StrongName post .... so likely within the next two months 🙂 Obviously this is going to break all the old links I had, so I'll also need to go back and update all of my old posts, since I won't want to keep two versions of the code base up on this blog.