为什么我不应该有一个单一的整体实用程序库?
我们有一些通用库(C#,但我想这不是特定于平台或语言的),我们称它们为 A、B 和 C。库 A 引用了 B 和 C,库 B 引用了第三方 DLL,库 C 是独立的。三个独立项目背后的想法是,每个库都有不同的功能,但随着时间的推移,库 A 或多或少成为了大多数客户端应用程序都会引用的“包罗万象”的通用库。只有少数应用程序引用了 B 和/或 C,而没有引用 A。
我们正在努力改进我们的源代码控制约定,我们正在尝试做的一件事就是正确标记和发布这些库 DLL,以便客户端项目文件可以指向代码的静态版本,而不是始终变化的主干。事实证明,这有点复杂 - 例如,一个客户端项目同时引用 A 和 B。A 本身引用 B,因此从技术上讲,有两个来自客户端项目的对 B 的引用。
因此,显而易见的事情似乎是将所有内容合并到一个具有组织良好的命名空间的通用/实用程序库中。正如我所说,几乎每个客户端应用程序都会引用这些库之一,所以谁在乎呢?这样做不会引入任何与第三方依赖项相关的不良情况,并且我们所有的目标计算机都是内部的,并保持大致相同的环境/软件配置。
但这似乎是一个太简单的解决方案,所以我想我至少会得到第二个意见。另一种方法是使用 GAC 并对所有内容进行严格签名/版本控制。我在这里遗漏了什么吗?
We've got a few common libraries (C# but I guess this isn't platform- or language-specific), let's call them A, B, and C. Library A has references to B and C, library B has a reference to a 3rd-party DLL, and library C stands alone. The idea behind three separate projects was that each library had distinct functionality, but library A has over time become a more or less "catch-all" common library that most every client app references. Only a few apps reference B and/or C without A as well.
We're trying to improve our source control conventions, and one thing we're trying to do is properly tag and release these library DLLs, so client project files can point to a static version of the code instead of the always-changing trunk. This is proving a bit convoluted - for example, a client project that references both A and B. A itself references B, so there are technically two references to B coming from the client project.
So the obvious thing seems to be to just combine everything into a single common/utility library with well-organized namespaces. As I said, almost every client app references one of these libraries, so who cares? Doing this won't introduce any undesirable situations with 3rd-party dependencies, and all our target machines are internal and maintain roughly the same environment/software configuration.
This seems too easy of a solution though, so I figured I'd at least get a second opinion. An alternative could be to use the GAC and strongly sign/version everything. Am I missing any catches here?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
我认为你整合到一个库中是正确的。
很多时候,代码被组件化为太多的可部署单元,而功能的逻辑部分似乎是分离的标准。国际海事组织这是错误的。程序集应该与部署场景和发布周期保持一致。否则,您最终会得到一个极其复杂的依赖关系图,其中无论如何每个程序集都是一起管理、构建和部署的。
不过很有趣的问题!让我们看看其他人的想法:)
I think you're right consolidating into a single library.
Very often code is componentized into too many deployable units whereas the logical piece of functionality seems to be the criteria for separation. This is wrong IMO. Assemblies should be aligned with the deployment scenarios and release cycles instead. Otherwise you end up with a horribly complex dependency graph where anyways every assembly is managed, built and deployed together.
Interesting question though! Let's see what other people think :)
这是一个经典的“金发姑娘和三只熊”问题。
您不需要一个单一的整体库 - 并且您不需要太多的库。你想要的库数量正好合适:)不要太多,也不要太少,恰到好处。
拥有不同的库有以下原因:
1)开发独立性——库可以独立开发。
2)更小的可部署性
我认为一般的经验法则可能是,如果有一个单独的团队致力于在库的特定部分进行全职开发,那么它应该是独立的。如果多个团队时不时地添加一些代码,那么开发和部署的独立性应该不会有问题,您也可能拥有一个通用库。听起来你的情况就是这种情况,所以选择一个库。
另一个要问的问题是“我们目前遇到的问题是什么,通过拆分图书馆可以解决吗?”如果它不能解决任何问题,那么就不需要单独的库。
This is a classic "Goldilocks and the 3 Bears" problem.
You don't want a single monolithic library - and you don't want too many libraries. You want exactly the right number of libraries :) Not too many, not too few, just right.
There are reasons for having different libraries:
1) Independence of development - the libraries can be developed independently.
2) Smaller deployable
I think that a general rule of thumb might be if there is a separate team that is dedicated to doing full-time development on a particular section of the library, it should be separate. If multiple teams add a few bits of code here and there every now and then, then there should be no issues with independence of development and deployment and you might as well have a single common library. It sounds like this is the case in your situation, so go with a single library.
Another question to ask is "What problem that we are currently experiencing would splitting up the library solve?" If it doesn't solve any problems, then no need for separate libraries.
观点1
拥有尽可能少的库可以简化构建脚本和部署(需要担心的部分更少)。拥有一个包含所有内部开发的 UI 组件的库对于启动新项目非常有用。只需添加该参考,所有内部组件就已准备就绪。希望这可以减少重新发明组件所花费的时间,因为有人忘记了已经有一个包含此类组件的库。通用实用程序库也是如此 - 最好只有一个,这样您只需一个参考即可获得所有可用功能。
观点2
将各种相关的功能分离到单独的库中可以使这些库保持重点并使其意图清晰。由于每个库都更加专注,因此每个单独的库都会更小。因此,您的最终部署包可以更小,因为您将仅包含您实际需要的库。但是,您必须记住您有多少个库以及每个库包含什么。这可能是文档和知识转移的噩梦。
那么对您来说,部署规模和开发人员可用性哪个更重要?选择优先级,然后将代码组织与其匹配。
View Point 1
Having as few libraries as possible simplifies build scripts and deployment (fewer parts to worry about). Having one library with all the internally developed UI components is great for starting new projects. Just add in that one reference and you've got all the internal components ready. Hopefully that reduces the time spent reinventing the components because someone forgot there already was a library with such a component. Same thing with a general utility library - it's nicer to have only one so you've got all the functionality available with one reference.
View Point 2
Separating the various related bits of functionality into separate libraries keeps those libraries focused and makes their intent clear. Since each library is more focused, each individual library will be smaller. Thus your end deployment package can be smaller since you'll include only the libraries you actually need. However, you'll then have to remember how many libraries you have and what each contains. This can be a documentation and knowledge transfer nightmare.
So what's more important to you, deployment size or developer usability? Pick the priority and then match the code organization to it.
我同意为这些实用程序拥有一个库是理想的,只要命名空间得到正确维护并且代码本身被很好地分解以供将来对库进行维护。我认为这样做的主要理由正是您提到的,几乎所有内部应用程序都在使用它。
然而,需要考虑的一件事是这些部件的功能。如果其中一部分是用于使用控件或标签执行巧妙技巧的实用程序命名空间,第二部分是处理登录过程的安全库,那么当“酷技巧 D”添加到实用程序库时,您可能会遇到一些意想不到的问题,但破坏了依赖安全库的现有应用程序,但由于整个 DLL 现已更新而被迫升级。
您可能会考虑以消除交叉依赖的方式重写所有三个库,并看看这是否能为您当前和未来的应用程序带来更好的整体情况。
I agree that having a single library for these utilities is ideal, as long as the namespaces are properly maintained and the code itself is broken up nicely for any future maintenance on the library. The main justification I see for this is exactly what you mentioned, nearly all your internal apps are using it.
However, one thing to think about is the functionality of these pieces. If one piece is the utility namespace for doing clever tricks with controls or labels, and the second piece is the security library that handles your login procedures, you may run into some unintended problems when "cool trick D" gets added to the utility library, but breaks an existing application that is reliant upon the security library, but is forced to upgrade since the entire DLL has now been updated.
You might consider rewriting all three libraries in a way that eliminates the cross dependencies and see if that makes for a better overall situation for your current and future apps.
可能有理由为具有完全不同目的的库或引用第三方库的项目建立单独的项目。除此之外,您可以将大部分内容放入公共基础库中。
我们有一个用于许多类的公共库,但有一个用于 Web 相关类的单独项目,一个用于 PDF 相关类的单独项目(因为它使用了我们在所有应用程序中不需要的第三方 DLL),一个用于MySQL 相关类(因为它使用第三方连接器)。
我们还有一个与数据库(MS SQL)相关的类的单独项目,但这实际上可以进入公共库,因为我们很少有应用程序不使用数据库。
There might be a reason to have separate projects for libraries with completely different purposes, or projects that reference third party libararies. Other than that you can put most in a common base libarary.
We have a common library for a lot of classes, but a separate project for web related classes, a separate project for PDF related classes (as it uses a third party DLL that we don't want in all applications), a separate project for MySQL related classes (as it uses a third party connector).
We also have a separate project for database (MS SQL) related classes, but that could really have gone into the common library as we have so few applications doesn't use a database.
我想说,这实际上取决于什么最适合你。一个大的实用程序库可能很难找到东西,但话又说回来,它都在一个地方,每个人都知道在哪里查找它们可能会更受益。另外,根据库的管理方式,不同的组可能更容易维护自己的 util 库(如果他们需要控制对它们的更改),但如果它由单个组管理(或者如果每个人都相处得很好),那么一个大问题一个可能更容易。所以真的无论什么对你有用。
I'd say it really just comes down to what works best for you. A big util library could be hard to find things in, but then again it's all in once place everyone knows where to look they may be of more benefit. Also depending how the library is managed, it may be easier for different groups to maintain their own util libraries (if they need to control changes to them), but if it's managed by a single group (or if everyone gets along) then one big one may be easier. So really whatever works for you.
只是分享一些最近的经验,这让我对此的观点略有改变......
将解决方案中的 150 个项目减少到大约 30 个,将我们的构建时间减少到大约 25%(1 分钟和更改)而在我们的典型开发机器上则需要 5 分钟)。如果您正在执行 dll 引用,那么这并不重要,但如果您将项目包含在主解决方案中,您可能会发现它很重要。老实说,我对这种差异感到有点惊讶,但过去的结果并不能保证未来的回报。
每次 .net 第一次加载 dll 时,您都会承担 JIT 和文件 I/O 开销。对于用户可能每天启动多次的 WinForm/WPF 应用程序,这是比 Web 应用程序更大的问题。即使对于 Winform/WPF 应用程序,对于许多应用程序来说这可能也不是那么大的问题。
另一件需要注意的事情是复杂的依赖关系,这会导致“如果我使用 A,我必须使用 B,因为 A 暴露了 B 的类型。同时,我很少单独使用 B”的情况,只需将其组合起来即可完成。
所以,我的理解是有一些具体的原因需要尝试巩固。可能有一百万个主观原因,但在大型解决方案文件中,最好尝试变得简单,因为您可以合理地完成。
更主观地说,我还鼓励您将项目文件视为构建工件而不是代码工件。将 .cs 文件视为您真正想要重用的文件,而不是 .csproj。当然,大多数时候您也会重用 .csproj 并始终以相同的方式构建程序集。但是,不要试图强迫自己拥有比项目中实际需要的依赖项或更多的代码@。大多数时候,.csproj 和 .cs 之间的关系相当松散。
编辑:@ - 添加“在你的项目中”
Just sharing some recent experience that has caused me to have a slight change in point of view on this...
Reducing 150 projects in a solution to about 30 has cut our build time to about 25% of what it was (1 minute and change vs 5 minutes on our typical dev machine). If you're doing dll references, it doesn't matter that much, but if you're including the projects in the main solution, you may find it matters. To be honest, I was a bit surprised at that difference, but past results don't guarantee future returns.
Everytime .net loads a dll for the first time, you take on JIT-ing and file I/O overhead. For WinForm/WPF apps where the user may launch it several times a day this is a bigger concern than web apps. Even for Winform/WPF apps, it may not be that big of a concern for many apps.
The other thing to look out for is intricate dependencies which cause situations where "if I use A, I have to use B because A exposes types from B. Mean while, I rarely use B by itself" Just combine it and be done with it.
So, my understanding is there are a few concrete reasons to try to consolidate. There's probably a million subjective reasons, but in a large solution file, it seems better to try to be a simple as you can reasonably pull off.
More subjectively, I would also encourage you to look at the project file as a build artifact and not a code artifact. Think about the .cs file as what you really want to reuse and not the .csproj. Sure, most of the time you would reuse the .csproj as well and just build the assembly the same way all the time. But, don't try to force yourself to have dependencies or a bunch more code than you actually need in your project@. The relationship between .csproj and .cs is reasonably loose most of the time.
EDIT: @ - added "in you project"