|
dev
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Single or multiple assemblies for big apps and code reuse?I have a question about .NET code sharing and reuse, and also about application design best practices / guidelines. Currently, we have many different .NET projects in source depot. Although they are different, in some of them we share C# code by referencing source files that are external (not part of the projects) on each project. For instance, some of our projects have the typical “sources†file with: SOURCES = \ ..\..\some_other_different_unrelated_project_A\fileA1.cs \ ..\..\some_other_different_unrelated_project_B\fileB1.cs \ ..\..\some_other_different_unrelated_project_B\fileB2.cs \ Program.cs Class.cs And so on. Some people in my team think that DLLs and assemblies are evil and should be completely avoided. Therefore, they advocate treating all projects in the depot as one huge, monolithic project (even they are not, as they are different projects), sharing code by referencing source files all over the depot. Basically, each application has one and only one assembly containing all the application source code plus all source code that belong to other projects too but is reused by referencing the other project(s) C# source files. Other team members (BTW facing huge opposition) insist in packing the shareable code into one or more assemblies, although for some people, assemblies and DLLs are absolutely forbidden. Can someone please tell me the pros and cons of each approach? Is it right to be completely against packing certain substantial modules or pieces of functionality into separated assembly/assemblies, as opposed to having one and only one single, huge monolithic assembly containing the whole application + other project source files? Those in favor of having shareable code packed into separate assemblies, instead of putting everything (all the source code of the application plus the sources of our libraries, plus the sources of all subsystems, etc.) into one, big monolithic assembly, point to these other URIs: http://msdn.microsoft.com/practices/compcat/default.aspx?pull=/library/en-us/dnbda/html/distapp.asp http://msdn.microsoft.com/practices/compcat/default.aspx?pull=/library/en-us/dnbda/html/apparchch2.asp http://weblogs.asp.net/savanness/archive/2003/07/22/10417.aspx http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconassembliesoverview.asp So, I wonder, are there any guidelines and/or best practices/patterns/anti-patterns in regards to C# source code sharing and reusing among different projects? Any authoritative answers? Is it reassonable to build big, different applications from one huge source tree, having only one and just one assembly per application and nothing more? Or it makes more sense to split the app into multiple assemblies, but keeping the number of assemblies to a minimum? Thanks and regards, Claudio What do you use to build your projects? I've used nant in the past - it had
no concept of a project, it was all file based compilation. I prefer to package common code in separate assemblies. We had two large applications sharing 3 common libraries. The hard part about shared code is coordinating the changes (which you're already doing). -Eric
Show quote
"Claudio Pacciarini" <ClaudioPacciar***@discussions.microsoft.com> wrote in There are many strange people in the world with strange ideas.message news:8DB9339B-0F5C-4D14-9B6A-C325B316E5D9@microsoft.com... > Hi everyone, > > I have a question about .NET code sharing and reuse, and also about > application design best practices / guidelines. > > Currently, we have many different .NET projects in source depot. Although > they are different, in some of them we share C# code by referencing source > files that are external (not part of the projects) on each project. > > For instance, some of our projects have the typical "sources" file with: > > SOURCES = \ > ..\..\some_other_different_unrelated_project_A\fileA1.cs \ > ..\..\some_other_different_unrelated_project_B\fileB1.cs \ > ..\..\some_other_different_unrelated_project_B\fileB2.cs \ > Program.cs > Class.cs > > And so on. > > Some people in my team think that DLLs and assemblies are evil and should > be > completely avoided. Therefore, they advocate treating all projects in the > depot as one huge, monolithic project (even they are not, as they are > different projects), sharing code by referencing source files all over the > depot. Show quote > Sharing source files between applicaions is usually a terrible idea. You > Basically, each application has one and only one assembly containing all > the > application source code plus all source code that belong to other projects > too but is reused by referencing the other project(s) C# source files. > > Other team members (BTW facing huge opposition) insist in packing the > shareable code into one or more assemblies, although for some people, > assemblies and DLLs are absolutely forbidden. > > Can someone please tell me the pros and cons of each approach? Is it right > to be completely against packing certain substantial modules or pieces of > functionality into separated assembly/assemblies, as opposed to having one > and only one single, huge monolithic assembly containing the whole > application + other project source files? > > Those in favor of having shareable code packed into separate assemblies, > instead of putting everything (all the source code of the application plus > the sources of our libraries, plus the sources of all subsystems, etc.) > into > one, big monolithic assembly, point to these other URIs: > > http://msdn.microsoft.com/practices/compcat/default.aspx?pull=/library/en-us/dnbda/html/distapp.asp > > http://msdn.microsoft.com/practices/compcat/default.aspx?pull=/library/en-us/dnbda/html/apparchch2.asp > > http://weblogs.asp.net/savanness/archive/2003/07/22/10417.aspx > > http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconassembliesoverview.asp > > So, I wonder, are there any guidelines and/or best > practices/patterns/anti-patterns in regards to C# source code sharing and > reusing among different projects? Any authoritative answers? Is it > reassonable to build big, different applications from one huge source > tree, > having only one and just one assembly per application and nothing more? Or > it > makes more sense to split the app into multiple assemblies, but keeping > the > number of assemblies to a minimum? > are better of creating multiple copies shared source files and letting each application maintain its own copy. At least then it's possible (through cut and paste and compare) to manage changes in the shared libraries. Otherwise, managing change in the shared source and its impact on applications is pretty hard. When one application requires a change to a shared source file, what happens to the other applications? The next time they get compiled they will pick up the change to shared file. But what if they are just doing a minor bug fix, and the change in the shared source file requires testing, or introduces another bug, or is incompatible with their existing source code? When you compiled version 1.2.0.2 of some application, what version of the shared source file was that using? There is no permanent record of exactly what version you used. There is no "1.2.0.2" version of the file, since it's shared among many applications., and you may never be able to figure out exactlly what source code went into the build. That being said, some source control systems can track and manage shared source files and provide resonable answers to these questions. But assemblies work so well, I wonder why you'd bother sharing source. David Hi Eric and David,
Thanks for your kind response. My goal is to help my team improve the way we design and develop some of our applications, and your emails will hopefully help me achieve that goal. Thanks so much. Claudio -- Show quoteClaudio Pacciarini "Claudio Pacciarini" wrote: > Hi everyone, > > I have a question about .NET code sharing and reuse, and also about > application design best practices / guidelines. > > Currently, we have many different .NET projects in source depot. Although > they are different, in some of them we share C# code by referencing source > files that are external (not part of the projects) on each project. > > For instance, some of our projects have the typical “sources†file with: > > SOURCES = \ > ..\..\some_other_different_unrelated_project_A\fileA1.cs \ > ..\..\some_other_different_unrelated_project_B\fileB1.cs \ > ..\..\some_other_different_unrelated_project_B\fileB2.cs \ > Program.cs > Class.cs > > And so on. > > Some people in my team think that DLLs and assemblies are evil and should be > completely avoided. Therefore, they advocate treating all projects in the > depot as one huge, monolithic project (even they are not, as they are > different projects), sharing code by referencing source files all over the > depot. > > Basically, each application has one and only one assembly containing all the > application source code plus all source code that belong to other projects > too but is reused by referencing the other project(s) C# source files. > > Other team members (BTW facing huge opposition) insist in packing the > shareable code into one or more assemblies, although for some people, > assemblies and DLLs are absolutely forbidden. > > Can someone please tell me the pros and cons of each approach? Is it right > to be completely against packing certain substantial modules or pieces of > functionality into separated assembly/assemblies, as opposed to having one > and only one single, huge monolithic assembly containing the whole > application + other project source files? > > Those in favor of having shareable code packed into separate assemblies, > instead of putting everything (all the source code of the application plus > the sources of our libraries, plus the sources of all subsystems, etc.) into > one, big monolithic assembly, point to these other URIs: > > http://msdn.microsoft.com/practices/compcat/default.aspx?pull=/library/en-us/dnbda/html/distapp.asp > > http://msdn.microsoft.com/practices/compcat/default.aspx?pull=/library/en-us/dnbda/html/apparchch2.asp > > http://weblogs.asp.net/savanness/archive/2003/07/22/10417.aspx > > http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconassembliesoverview.asp > > So, I wonder, are there any guidelines and/or best > practices/patterns/anti-patterns in regards to C# source code sharing and > reusing among different projects? Any authoritative answers? Is it > reassonable to build big, different applications from one huge source tree, > having only one and just one assembly per application and nothing more? Or it > makes more sense to split the app into multiple assemblies, but keeping the > number of assemblies to a minimum? > > Thanks and regards, > > Claudio > Hi Claudio,
Did you get any other replies to your question? On the surface it seems like a slam dunk answer. However, since being in a production environment initially starting with a C++/MFC client server app, and watching the pain managers go through not to change it, the benefit of smaller projects has been well illustrated. Html web pages, database triggers and stored procedures run circles around the C++ development process, delivering much faster (and buggier??). The C++ development process is more rigid, stricter, and taking more time. On the flip side these developers don't typically have issues with getting the correct version, or wondering if they have the correct version of files. In the various environments html pages, triggers and stored procedures have constant issues with having the correct versions. SQL Server 2005 seems to have better interface with Source Safe, and that might make things better. The Asp.net enviornment has potential to go either way. Monolithic or the compete opposite with single self containted??? pages, or assemblies. What is the answer? mark These are the other MSDN newsgroups where I posted my questions too:
http://msdn.microsoft.com/newsgroups/default.aspx?query=Single+multiple+assembly+apps&dg=&cat=en-us-msdn&lang=en&cr=US&pt=&catlist=774F24A2-F71F-425F-AC2B-DC48AB0DA5C9&dglist=&ptlist=&exp=&sloc=en-us Thanks and regards, Claudio Pacciarini Show quote "Mark Edwards" wrote: > > Hi Claudio, > > Did you get any other replies to your question? > > On the surface it seems like a slam dunk answer. However, since being in a > production environment initially starting with a C++/MFC client server app, > and watching the pain managers go through not to change it, the benefit of > smaller projects has been well illustrated. > > Html web pages, database triggers and stored procedures run circles around > the C++ development process, delivering much faster (and buggier??). The C++ > development process is more rigid, stricter, and taking more time. On the > flip side these developers don't typically have issues with getting the > correct version, or wondering if they have the correct version of files. In > the various environments html pages, triggers and stored procedures have > constant issues with having the correct versions. SQL Server 2005 seems to > have better interface with Source Safe, and that might make things better. > > The Asp.net enviornment has potential to go either way. Monolithic or the > compete opposite with single self containted??? pages, or assemblies. > > What is the answer? > > mark Hi Mark,
Thanks for asking; yes, I've got plenty of answers; in general the consensus is: 1) Do not share/reuse .NET code referencing source files directly, share assemblies. 2) Favor a reduced number of larger assemblies instead of a large number of small assemblies, within reasonable limits. 3) Keep in mind that the upcoming CLR versioning may remove the static library concept. 4) Assemblies (or DLLs, for that matter), should generally be organized around the subsystems of an application. If you have a UI section and an underlying processing engine, that's a reasonable place for an assembly break. 5) The number of assemblies that you load initially can be a big factor in startup time, so you'll want to keep that down (this doesn't trump other guidelines, just something to keep in mind). 6) Optional code - code that isn't always used, or is only used in a certain scenario - is a good candidate for a separate assembly. 7) Don't guess on the performance impact. Track how long it takes to start your app, and how much of an issue it is. 8) The namespaces in the managed world may give you a hint on how to factor into assemblies. 9) For examples, study existing, well known .NET applications, such as NUnit, the Enterprise Library, FXCop and many others. One of the persons that kindly answered my questions also provided his views about Pros and Cons of static and dynamic linking: Static linking - Pros: - The application is completely self-contained. Basically, everything you depend on is in a known state, in a known place and there's no room for surprises. - No OS overhead for loading multiple modules. Plus you don't need to worry about getting DllMain right in the case of native apps or managed IJW assemblies. Also, no rebasing concerns. - Easy deployment. Just get the EXE and run it (well, N/A for managed client apps anyway...). Cons: - Servicing. For N applications, the cost of fixing a bug in a common component is multipled by N, because you have to hunt down each binary that contains the bug. N can be small or huge, but it's always greater than 1. - Performance. If one runs several instances of the apps at the same time, there is no code sharing. - Code rot. You end up knowing internals about someone else's component, take dependencies on them and make everyone's life miserable when interfaces aren't cleanly defined and separated anymore. This is especially valid for source level sharing (i.e. if you link statically against a C++ lib, you don't have access to the internals, but if you just take a piece of C++ or C# code and add it to your project, things are way different). You essentially render C#'s "internal" useless. If anyone thinks that's a small annoyance, think about the Windows layering disaster. Dynamic linking - Pros: - Servicing and performance. You have a "single point of truth" where the code lies and can be patched, and it can be shared among different apps (as in, working set sharing). For managed apps you will need to Ngen the shared assembly, though. - Clean boundaries between components. Prevents code rot, simplifies security reviews and makes everyone a bit happier. Cons: - DLL hell for native apps. You have to be really careful not to break the contracts of public interfaces between versions. Solved since Windows XP via side-by-side execution of native components. The same technology is used for managed assemblies as well. It can lead to "versioning hell" if you're not careful, but it tends to work out nicely with a small amount of up-front planning. - The overhead of loading multiple modules in a single process and of getting the base addresses right. Afaik, Windows tends to behave decently for up to ~100 modules loaded into a process. The ideal figure would be around 20, but given the layering hell we're in now, the average figure tends to go towards 40-50. Bottom line: Dynamic linking in the large is great (i.e. you have a small number of large assemblies, with large pieces of code in the DLLs being used by several apps). Dynamic linking in the small (e.g. a 1000 line utility library in its own assembly) tends to be a bad idea. Conversely, static linking in the small tends to be fine (for really small amounts of utility code, in a small number of dependent apps). Generally, when larger amounts of code start to be linked into several apps, it's a good idea to switch to dynamic linking. Finally, these are the MSDN newsgroups where I also posted my questions; you may find interesting the answers I received there as well. Thanks and regards, Claudio Pacciarini Show quote "Mark Edwards" wrote: > > Hi Claudio, > > Did you get any other replies to your question? > > On the surface it seems like a slam dunk answer. However, since being in a > production environment initially starting with a C++/MFC client server app, > and watching the pain managers go through not to change it, the benefit of > smaller projects has been well illustrated. > > Html web pages, database triggers and stored procedures run circles around > the C++ development process, delivering much faster (and buggier??). The C++ > development process is more rigid, stricter, and taking more time. On the > flip side these developers don't typically have issues with getting the > correct version, or wondering if they have the correct version of files. In > the various environments html pages, triggers and stored procedures have > constant issues with having the correct versions. SQL Server 2005 seems to > have better interface with Source Safe, and that might make things better. > > The Asp.net enviornment has potential to go either way. Monolithic or the > compete opposite with single self containted??? pages, or assemblies. > > What is the answer? > > mark |
|||||||||||||||||||||||