handling dependencies to a frequently-changing DLL - c#

we have a number of c# projects that all depend on a common DLL (also c#). this DLL changes somewhat frequency as we're in an environment where we need to be able to build and deploy updated code frequently. the problem with this is, if one of these updates requires a change to the common DLL, we end up with several client apps that all have slightly different versions of the DLL.
we're trying to figure out how to improve this setup, so we can guarantee that anyone can check out a project (we use SVN) and be able to build it without issue. it seems like tagging each and every DLL change to a new version is excessive, but I'm not sure what the "right" solution is (or at least something elegant).
it would be ideal if any solution allowed a developer to be able to step into the DLL code from visual studio, which only seems to be possible if you have the project itself on your machine (might be wrong there).

Frankly, I think versioning your DLL in source control is the RIGHT solution.
It's very possible that a quickly changing core DLL could cause binary and source compatibility in a client project. By versioning, you can prevent each project from using the new DLL until you're ready to migrate.
This provides a level of safety - you know you won't break a client's project because somebody else changed something underneath you, but it's very easy to upgrade at any time to the new version.
Versioning in SVN is trivial - so I wouldn't let this be an issue. It's also safer from a business perspective, since you have a very clear "paper trail" of what version was used with a given deliverable of a client project, which has many benefits in terms of billing, tracking, testability, etc.

There's no easy solution - and the previous two answers are possibly the more accepted method of achieving what you want. If you had a CI environment, and were able to roll out all of your apps on-demand from a store that was built via CI, then you could avoid this problem. That can be lofty ambition, though, if there are old apps in there not governed by tests etc.
If your application is .Net 3.5 (might even need the SP1 too) then did you know that assemblies that are loaded from the network now no longer have any trust restrictions? This means that you could configure an assembly path on the machines in question to point to a shared, highly available, network location - and have all of your apps locate the assembly from there.
An alternative to this, but which would achieve the same goal, would be to build a component that hooks into the AppDomain.CurrentDomain.AssemblyResolve event - which is fired whenever the runtime can't auto-discover an assembly - and do a manual search in that network location for the dll in question (if you were to take the AssemblyName portion of the Full Name, append .dll to it, then you'd be reproducing the same search that the .Net Fusion binder performs anyway).
Just a thought ;)

I think you could benefit from setting up a continuous integration server with targets for each of the client projects and the common DLL project.
This way you'll immediately know when changes in the common DLL breaks any of the client projects. It could reduce the trouble of updating client projects when common DLL's interface changes. This solution might be inadequate if you development team is distributed and very large.
I wouldn't say there is a RIGHT solution though. There are many ways to manage dependency problems.
You could also have a look at Maven. It will help you set up project dependencies. Not sure how you can integrate Maven into Visual Studio though. Maven will allow you to specify which version of a project (in SVN) you want to depend on. Developers will then be able to checkout the correct project version and build their projects. Maven will checkout the correct version of the dependent projects from SVN for them. I haven't work with it myself, but a lot of open source projects in the Java community uses it.

Related

Do we need Assembly version numbers in a asp.net mvc website project?

Situation - We have a .net mvc solution with WCF layer. the solution has about 20 odd projects that get compiled into DLL. the site is running on SQL server 2008. we maintain the SQL scripts in the solution folder as versions. So we have SQL scripts eg. version 1.0.0.0 to lets say latest which is 3.0.0.1.
the solution is source controlled in TFS, we also use TFS to manage the work items, bugs etc etc. SQL script files are also in TFS
Question - the question is that do we need version numbers on the assemblied i.e. dlls aswell. Our DLLS are not exposed in any way or from to the outside world they are just in the runtime of the mvc app. we do not expose the WCF to outside clients,again its just used by the mvc app.
the deploy process is simplly the latest code against the latest db, so when we deploy we check what version the db is in and run a tool to upgrade it to the latest version that is in the db project in the solution.
One of our senior architects is saying that we should maintain the version numbers in the assemblies aswell. I am saying that we dont need any version numbers in the code. beacuse TFS manages that. when we release we just deploy the latest code with the latest assemblies/ deploy package.
I have not come accross the assembly versions unless them assemblies where released to the outside world (if you know what i mean)
please can you suggest... Also note we dont do feature development its just version numbers so that we know what version a particular DB is at.
I would prefer the security of knowing and being able to double check versions. If there were a problem with the publishing process, or there were a bug that manifested itself that appeared to be a publishing problem I would want to rule things out as quickly as possible. I also think that it's so easy to implement you've spent more time discussing and thinking about it than you would have actually spent doing it, and there is no down side to it that I can think of.
In a similar project at my job, we use version numbers.
Every commit against the version control system (VCS) causes our CI server (TeamCity) to build a new artifact, with the version set to "LATEST". Every successful build of "LATEST" get deployed automatically to our test environment. We could, in theory, also deploy this "LATEST" version to production, but we don't.
When we want to deploy a new version to production we run a different, manual build job which creates a versioned release (e.g. 1.4.7). The build job also creates an SVN "Tag" of the current codebase. To have our DLLs have the appropriate version, we use TeamCity's AssemblyInfo Patcher feature. This way, we don't have to constantly manually update our projects' AssemblyInfo.cs files. Instead, they get to always have placeholder version info like this...
[assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyFileVersion("1.0.0.0")]
These number get automatically updated during the build by TeamCity. The versioned artifacts (which include any corresponding SQL scripts) are saved to our "Releases" directory where we keep all our versions of the codebase.
Now this all seems like overkill, right? Not really.
This gives us the following benefits...
Our deploy process does a wget to our monitoring page which lists the version number and asserts the versions match up (version expected to have been deployed vs. the version currently running on the server). This gives us confidence that our deploy process worked properly.
If bugs are found in the versioned release (the production release candidate), we can SVN checkout the tag, apply a fix, and create a new release without having to worry about other changes on trunk which could compromise the release. It is hard to stay "releasable" all the time, this allows to not have to be. Although, don't get me wrong, it has it's advantages.
If problems are found with a versioned release but they can't be resolved quickly, you can always just re-deploy the older artifact which is known to work. Being able to revert a deployed release to an older version has definitely saved us on a couple occasions.
If bugs are found on production that need to be investigated, we are free to deploy the same versioned artifact to any of our test environments so that we can try to reproduce the problems outside of our production environment.
There are probably more advantages I am forgetting at the moment but the above list should give a general idea of the power that proper version management can bring to the table.
What I would advise against is continuously, manually updating 20+ projects' version files. This seems like a lot of busy work which is mostly a waste of time because it is prone to human error. Whatever you decide to do, automate it and verify the results.

Reducing dependencies through IoC

In a quest to reduce the dependencies in my projects, I now have everything depending on and implementing interfaces, and they are glued together by an IoC container. This means projects need only to have direct references to such interface libraries.
However, if you don't specify the project as having a reference to the implementation (even though you don't need it at compile time) the implementation libraries are not included with the executable or in the setup project.
Is in a way Visual Studio promoting bad practices by requiring explicit references when they are not needed? Is it possible to have the dependencies only to the required interfaces and in this case what is the best method to get the implementation libraries available?
Is in a way Visual Studio promoting bad practices by requiring explicit references when they are not needed?
Not really. Your issue is one of deployment, not building.
Deploying an application and building it are separate things - if you have a good deployment strategy, you will be deploying implementations where they belong.
Is it possible to have the dependencies only to the required interfaces and in this case what is the best method to get the implementation libraries available?
The easiest way is indeed to reference the implementation assemblies. This will definitely make building and running locally as easy as F5, but do you really want that? To be honest, if you and your team have the discipline to only code to interfaces, that's all you need (and there are static analysis tools like nDepend that help with ensuring that remains the case).
One way forward is to create a deployment script that will deploy all dependencies whether local or elsewhere.
Visual studio does not require these references, but your IoC container does.
When adding a reference to the project, its binaries are automatically included in the output folder, which is necessary for your IoC container to glue the code together. There are other ways to get these binaries to the output folder than referencing their projects in Visual Studio - perhaps a post-build step?
No. It is simply the minimum they need to do in order to give developers working code without them having to do anything extra (aside from hitting F5) or for all references to be added by default (which would likely be a mess and slow on older hard discs.
For local development builds, you can simply have a post-build step on the relevant project to copy the DLLs to the main working directory. Just make sure the project is added to the active configuration to be built, other wise you'll go through a whole annoying debug session on the post-build only to realise there was no-build... lol
VS 2010. Post-build. Copy files in to multiple directories/multiple output path
Copy bin files on to Physical file location on Post Build event in VS2010
For full-scale application deployment, you'd likely be looking at Visual Studio setup projects at a bare minimum, but more ideally something like WiX or another deployment tool-set.

What is the best way to make shared libraries available to multiple applications?

Like most shops we've got a team of people working on various projects that all need to access the same core information and functions that relate to our business, usually in C#. We're currently just copying common classes from project to project, but everyone is starting to have their own flavors and we want to consolidate.
We use Tortoise SVN and have decided to maintain a separate project to contain our common classes, but are not sure the best way to deploy this common code to our various applications. We work for an internal IT shop that can dictate everything about how the users access the applications, we don't have to worry about releasing our products into the real world.
Some of our thoughts have been:
Compile the classes into a single DLL and load it into the Global Assembly Cache (GAC)
Compile the classes into a single DLL and save it to a centrally located shared drive to be referenced by all other projects
Compile the classes into a single DLL and include it in each project
Just fetch the most recent classes when starting a project, but don't have a central shared library (our interpretation of this: http://www.yosefk.com/blog/redundancy-vs-dependencies-which-is-worse.html)
SVN Externals http://svnbook.red-bean.com/en/1.0/ch07s03.html
I know this is a common problem, and if you spend any time looking into these or other options, you invariably find people explaining the pitfalls of each method (versioning, regression testing, "DLL Hell", "The GAC sucks", etc). I can hardly find anyone talking about what WORKS and why. Is there a preferred method?
At my company we have the same issue. Currently, we just use .bat files that go to our SVN Trunk and pull the most recent .dll references and fill a local References folder for the project you are working on.
However, we are currently working on switching this system over to NuGet. I'm not 100% sure how it works, but it's definitely worth looking into. Looks like you can set it up to where you can point it to a shared code repository, and then in Visual Studio using a plugin, it's as simple as just right clicking and hitting 'Update' everytime you need to get the newest code.

How to manage versions of a software in a CVS with lots of libraries

We are developing a large software project which consists of a large number of projects, components and libraries. Our management has decided that for every deployment a snapshot of the entire system has to be saved so when a problem arises we can easily have the exact version of the entire system. The usual solution would be to branch the project after each deployment. And by the way, we are using VS2008, C# and SVN. But this is not practical beacase of the large number of sub-projects and libraries which also have their versions and are modified.
One answer to this problem is to have backwards compatibility and always fix problems on the trunk version, but in our case it would not be possible to test the changes of the system ( the software is an ITS system and once a system is deployed we can't do any more intergration testing).
And to make matters worse, out deploments are modular, so each time a different combinations of components is deployes and there is also the localization.
How are you resolving these kinds of problems? Are there any tools that can help?
You could use a dependency management system like ivy - this essentially keeps a record of every version of every dll you are using.
As a (very) brief overview, when you do a build (using nant, for example), you can hook in ivy to resolve all of the dependencies, getting the specific versions of dlls that you need. As the ivy config will be in svn, if you get out an older revision of your code, you also get out an older version of the ivy config.
I used to work on such project.
We used to branch each release candidates and report bugfixes applied to the RC branch onto the trunk. That was not really handy, but we could not find a decent alternative until we decided to split the projet into a lot of small and cute projects managed by a maven-like system.
Maybe using some continuous integration management tool associated to strong testing routines could help, too.

.net library (dll) optimization

I am trying to using PDF Library ITextSharp, in my project. ITextSharp has so many features, i am not using even 5% of it. I am just wondering, why i should ship the complete dll file, when i use only 5% of it.
Is there any way to statically link the library to my project and remove all unused methods,features from the library ?
Disclaimer: I work for the company whose product I'm going to mention. I do know that other tools can do this as well but I only have direct experience with this one.
It is not necessary to modify any of the ITextSharp source or to perform your own custom build. It is possible to achieve all that you need with just the assemblies in your bin directory.
You can use Dotfuscator (the Removal option) to perform static analysis of the entirety of your application and output an assembly that only contains code that is actually used in your app. In addition you can use the Linking feature to link the DLL into your exe so that you are only shipping one file to the customer. This can result in a significantly smaller application footprint. You can take advantage of all of this functionality even if you choose not to use the obfuscation features that make you application harder to crack and reverse engineer.
Dotfuscator can be added into your build process in a number of ways, we integrate directly into Visual Studio (versions 2002 through 2010) so that you can just build your solution, there is also an MSBuild task for using on a Team Build server (if you choose not to have the build server build your solution), as well as a command line version for any other build system.
Dotfuscator will work on any .NET assembly type from including Silverlight assemblies.
These features are only available in the Pro version of Dotfuscator, if you contact PreEmptive Solutions we can set you up with a free, time limited evaluation so you can see how the product works for you.
If you just want to perform linking of assemblies there is also the ILMerge utility from Microsoft Research that will link multiple .NET assemblies into a single assembly.
There is no benefit of static linking with .NET dlls.
Its not easy to judge that you are using only 5% of the library, library may be using so much of internal code inside it to do lots of small small things that may not be seen by naked eye.
However iTextSharp is open source, you can create striped down version of iTextSharp to ship with your project.
By the way iTextSharp is smaller quite compared to earlier dlls required on non .net days.
Without modifying the source code and building your own .dll, no there is no way to not ship the entire thing. Additionally, if you wanted to head the route of creating your own modified .dll, please be aware of any possible licensing issues involved (I don't know if there are any, but it's certainly something you should be aware of). And finally, I would add, I don't know how big the iTextSharp .dll is, but really ask yourself if however much space it takes up actually matters.
If you want to reduce the size you have two options an obfuscator or an assembly compressor.
I haven't used any obfuscator for .Net just for Java so I can't recommend you any but they do what you pretend: remove unused methods and classes.
Or you can create a single compressed executable with all the needed assemblies that is auto decompressed when started like the popular Aspack and UPX do for windows executables http://en.wikipedia.org/wiki/Executable_compression . I have tried .NetZ and was happy with the results.
In this type of situation, your best bet is the site where you downloaded the code.
In many cases they use conditional compilation to include/exclude certain pieces. If the code isn't written with conditional compilation in mind, it will be "difficult" to do it yourself.
I personally would not recompile the source, unless there is a bug that needs to be fixed and you cannot wait for a new release. The time spent on the changes is time lost on your main project (the one you're getting paid for).

Categories

Resources