There are essentially two ways to do this. Which one is suitable for you depends on what you want to accomplish.
Case 1: A, B and C are loosely related, that is if e.g. B can be used without A and C. Having A and/or C available would extend the functionality of B.
Case 2: A, B and C are tightly related and some part of A, B or C relies on the existence of A, B or C. Together they form a logical unit.
If Case 1 fits your projects' purpose, then you want to build separate node modules and have the end user pull in those modules and use them at will.
If Case 2 fits better, then you want to compile A, B and C into one module e.g. ABC. You can still structure the source code (and exported API) of the ABC module according to A, B and C.
Building three separate modules and linking them dynamically makes little sense. In fact, they are dynamically linked (by node) when imported (require
'd) in node-land. Linking them together statically might make more sense, bus is essentially just a messier way of accomplishing "solution 2" (producing a single module).
Edit:
If A, B and C are three modules that are not authored by you, then you are dealing with a hierarchy. As you explain it in your hypothesis, the hierarchy of dependance is:
B --requires--> A
C --requires--> B
C --requires--> A
Thus A could be "owned" by B, and B could be owned by C. If you author C, then provide a user-facing API with an entry-point in JavaScript, where you require
the three modules. Compile A, B and C as separate modules and have them live "inside" your compound module. The file system structure could look something like this:
foo/ # Your compound module
foo/index.js # require('./_A'), require('./_B'), require('./_C')
foo/_A.node
foo/_B.node
foo/_C.node
As the code in _C.node requires certain symbols to be implemented (i.e. the depending symbols from A and B), you will need to load the modules in order.
Note that I have not tested this, but in theory, this should work.
The method of storing the key pair depends very heavily on how badly you want to protect it from undesired use. Personally I store my keys in a folder protected by the standard ACLs (so anybody who manages to get admin access to my machine can get to my key pairs). For me that's good enough given that my key pairs aren't that valuable. Microsoft recommends using a key container.
If you want to avoid having to synchronize your key pairs between machines then it is probably best if you were to build the release version of the libraries on one single machine (either your PC or the laptop) and make that machine the 'build machine'. In that case depending on where you are storing your key pair (in a file protected by ACLs or in a key container) you can use either one of these techniques:
If you keep the key pair in a file:
- Create public/private key pairs for both computers. You can copy the key pair but that's not required, generating individual ones for each machine is equally valid.
- On each machine create an environment variable that points to the location of the key pair on that specific machine. Make sure the environment variables have the same name on both machines.
To allow you to share code between the machines and still use the machine specific key files add the following section to your C# project file.
<PropertyGroup>
<SignAssembly>true</SignAssembly>
<DelaySign>false</DelaySign>
<AssemblyOriginatorKeyFile>$(YOUR_ENVIRONMENT_VARIABLE_HERE)</AssemblyOriginatorKeyFile>
</PropertyGroup>
If you also want the key to show up in the 'properties' section of the project then you can add the following section
<None Include="$(YOUR_ENVIRONMENT_VARIABLE_HERE)">
<Link>Properties\App.snk</Link>
</None>
If you keep the key pair in a key container:
- Create public/private key pairs for both computers and store them in the key containers. Make sure you use the same name for the key container.
To allow you to share code between the machines and still use the machine specific key files add the following section to your C# project file.
<PropertyGroup>
<SignAssembly>true</SignAssembly>
<DelaySign>false</DelaySign>
<KeyContainerName>YOUR_CONTAINER_NAME_HERE</KeyContainerName>
</PropertyGroup>
In this case I'm not sure if you can link the key from the 'properties' section (I suspect not).
Using either one of these ways allows MsBuild to find your key and use it during the build while still giving you a (semi-)portable way of dealing with different keys on different machines. Just make sure that you always build your release version of the libraries on the same machine (which will have one set of keys), otherwise you get releases done with different keys.
As for key-pair hell, the only thing you can't do is move the bin folders from one machine to another and expect partial builds to work. If you rebuild the libraries then there shouldn't be any problems.
Best Answer
Using Nuget for library dependencies goes a long way toward dependency declaration and isolation.
The packages.config associated to each project can be read as a dependency declaration.
If those package references are marked 'private', they are bundled into the bin folder of your build outputs, and are presumably bundled for deployment. This avoids the requirement that all reference assemblies are GAC'd on the deployment box.