Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Build a Visual Studio Project without access to referenced dlls

I have a project which has a set of binary dependencies (assembly dlls for which I do no have the source code). At runtime those dependencies are required pre-installed on the machine and at compile time they are required in the source tree, e,g in a lib folder. As I'm also making source code available for this program I would like to enable a simple download and build experience for it. Unfortunately I cannot redistribute the dlls, and that complicates things, since VS wont link the project without access to the referenced dlls.

Is there anyway to enable this project to be built and linked in absence of the real referenced dlls?

Maybe theres a way to tell VS to link against an auto generated stub of the dll, so that it can rebuild without the original? Maybe there's a third party tool that will do this? Any clues or best practices at all in this area?

I realize the person must have access to the dlls to run the code, so it makes sense that he could add them to the build process, but I'm just trying to save them the pain of collecting all the dlls and placing them in the lib folder manually.

like image 601
David Reis Avatar asked Mar 16 '10 08:03

David Reis


People also ask

Should DLLs be in source control?

Some companies have a policy to put commonly used assemblies (DLL's) into source control. If you own the source code, this should never be done. These assemblies should be built during the build process.


2 Answers

Maybe one of these ideas will help you to solve the problem:

  • Derive interfaces from all classes in the 3rd party dlls. Put these interfaces into an own project (same solution) and add a reference to this interface assembly. Also add an EventHandler to AppDomain.AssemblyResolve and try to find and load the assemblies at run-time. (Credits go to NG)
    • Depending on how big the dlls are and how often changes are made to the public part this can get a real pain.
  • Provide a readme.txt where you explain how to get the needed assemblies and where the user should put them relative to the project path. Normally VS is smart enough to remove the exclamation mark right after you put the assembly into the right spot, where the project references it from (maybe you have to press refresh in Solution Explorer) (Credits go to Paul)
    • Don't forget to add the readme.txt also to your solution by right clicking on your solution and select 'Add -> Existing Item'. In this case it will get a quite prominent place within visual studio Solution Explorer and the user can read it on a double click.
  • Create another project within your solution that is able to download all the needed dlls automatically and to put them into the right spot. Maybe it should check beforehand if these needed files are already there before it starts to download. Set the Project Dependencies of your original project, so that it will depend on this one. So it will always be built before your original one. Then start this download helper tool in the pre-build event of your original project and don't forget to exit your program with an int value. 0 means success, any other error and so also Visual Studio knows if your tool was successfull and stops the compile process before hanging on missing dlls.
    • Maybe it is nearly impossible to automatically download the files, cause you need a login to a webpage or some cookies, flash, captcha, etc. is used which can't be automated by a tool.
like image 104
Oliver Avatar answered Nov 15 '22 09:11

Oliver


To all the good advice above, agreed. That being said, maybe there is a valid scenario where the external DLL's are generally not needed? So here is what you do. You wrap and isolate them. (Its a higher level of abstraction than creating interfaces, so a bit easier to maintain).

In Visual Studio, if you do not recompile the specific VS Projects which reference the external DLL's then you can get away with compiling the rest of the VS Solution's Projects without having those DLL's handy. Thus if you somehow wrap the external DLL's with your own DLL's and then distribute those wrappers as binary only, the person sharing your source code will not need the external DLL's to compile the main solution.

Considerations: 1. Extra work to separate out the wrapper code into isolated Projects. 2. The other VS Projects must add references to your wrapper DLL's as "File System" references to a "LIB" folder, rather than "Project References". 3. The VS Solution configurations must disable compile for the wrapper DLL's. A new configuration should be added to explictly re-compile them, if needed. 4. The VS Project definition for each of the Wrapper DLL's should include a post-build event to copy them to the expected "LIB" folder location. 5. At runtime, the external DLL's must be present in the application's bin directory, or the machine's GAC, or otherwise explictly loaded. NOTE: If they are missing, it is only when they actually invoked at runtime that their absence will result in a runtime error. i.e. You do not need to have them if the code doesn't happen to call them in a general situation. 6. At runtime, you can catch errors loading the external DLL's and present a pretty error message to the user to say "In order to user this function, please install the following product: xyz". Which is better than displaying "AssemblyLoadException... please use FusionLogViewer... etc" 7. At application startup, you can test and detect missing DLL's and then disable specific functions which depend upon them.

For example: According to this pattern I could have an application which integrates with Microsoft CRM and SAP, but only for a specific function, i.e. Import/Export.
At design time, if the developer never neeeds to change the wrapper, they will be able to recompile without these external DLL's. At runtime, if the user never invokes this function, the application will never invoke the wrapper and thus the external DLL's are not needed.

like image 25
Jennifer Zouak Avatar answered Nov 15 '22 09:11

Jennifer Zouak