Code Contributions Guideline

If you want to contribute to the project then grab the latest code from Git and after you are happy with your implementation create the PullRequest.

As an architectural guide line there are few points that are not necessarily obvious:

Avoid bluntly implementing WiX schema
Wix# isn't a C# binding for WiX. It is a new API interface (an adapter) that is an attempt to shield user from the need to deal with the complicated WiX XML schema.
  • WiX maps (and works) with MSI tables (e.g. "need to add entry in the CreateFolders table").
  • Wix# maps deployment requirements (e.g. "need to deploy file into Program Files").
Wix# and WiX are ultimately related but they are working on completely different levels and serving very different purpose. This is the reason why Wix# does not deal with many WiX entities (e.g. Component). You can read more about the Wix# fundamental purpose on InfoQ

Push XML generation into Wix# entities
When possible place XML emitting routines in the corresponding entities. Initial Wix# code architecture was revolving around Compiler class. Today when the volume of code base is much higher the Compiler.BuildWxs is becoming a heavy wight routine, which is desirable not to overload with new XML emitting functionality. The all recently added types now contain ToXml() method that Compiler is using to obtain the XML. Thus Compiler is mainly responsible for the placement of this XML but not for its generation. The Compiler.ProcessCertificates and Certificate.ToXml is a good example for illustrating the point. The following is the Certificate.ToXml implementation:

public XContainer[] ToXml()
{
    var element = new XElement(WixExtension.IIs.ToXNamespace() + "Certificate");

    element.SetAttribute("Id", Id)
           .SetAttribute("BinaryKey", BinaryKey)
           .SetAttribute("CertificatePath", CertificatePath)
           .SetAttribute("Name", Name)
           .SetAttribute("Overwrite", Overwrite)
           .SetAttribute("PFXPassword", PFXPassword)
           .SetAttribute("Request", Request)
           .SetAttribute("StoreLocation", Enum.GetName(typeof(StoreLocation), StoreLocation))
           .SetAttribute("StoreName", Enum.GetName(typeof(StoreName), StoreName));

    return new[] { element };
}


Benefit from an extensive XML manipulation Wix# API
The Wix# XML fluent method extensions allow simple XML manipulations without dealing with namespaces. Thus all lookup operations are based on the matching LocalNames instead of Names. For all practical reasons it is much more convenient then specifying the namespaces all the time. The extensions map all major lookup operations:

//XContainer.Single equivalent
document.FindSingle("Package");
 
//XContainer.Descendants equivalent
document.FindAll("Package");
 
//XPath equivalent
document.Select("Wix/Product/Package");

The SetAttribute extension is smart enough to decide if the attribute needs to be created, updated or not changed depending on its existence and the value passed by the developer. SetAttribute can process key/value pair(s). It also handles nullables (e.g. bool? is not added/set unless it has a value). And it also translates bool into a WiX compatible "yes/no":

//This is an extended fluent version of XElement.SetAttributeValue
element.SetAttribute("Count", 10)
       .SetAttribute("Title=Testing")
       .SetAttribute("Compressed=yes;SummaryCodepage=Windows-1252;Languages=1033")
       .SetAttribute("KeyPath", globals.UsingKeyPath);


When possible document your contribution
Xml code documentation (at least for public members) is obviously desirable. GhostDoc can be a great help.
Also when it's applicable create a "Hello World" style sample in the sample folder. If you do so then UnitTesting will automatically run your build.cmd during the test.

Last edited Nov 28, 2016 at 12:52 AM by oleg_s, version 4