﻿<?xml version="1.0" encoding="utf-8"?><rss version="2.0"><channel><title>Ayende @ Rahien</title><link>http://ayende.com</link><description>Ayende @ Rahien</description><copyright>Copyright (C) Ayende Rahien  2004 - 2021 (c) 2026</copyright><ttl>60</ttl><item><title>Patrick Smacchia commented on Handling dependencies in a one assembly</title><description>Ayende, thanks for quoting NDepend.
  
  
For those who are considering the option of using NDepend to handle internal dependencies and layering into big projects, you can read an article I wrote about this subject:
  
  
http://www.theserverside.net/tt/articles/showarticle.tss?id=ControllingDependencies
  
  
The article bring several advantages on using few big projects instead of multiple small ones. Basically you get less cost:
  
-  Cost at development time
  
-  Cost at compile time 
  
-  Cost at deployment time
  
-  Cost at runtime
  
  
On our particular case, VisualNDepend.exe is an assembly made of 35K lines of logical code (i.e more than 200.000 lines of physical code) splitted in more than 40 namespaces/components, and it is a real joy to eat our own dog food to maintain a good layering.
  
And also, VisualStudio takes between 1 and 5 seconds to compile all this big code.
</description><link>http://ayende.com/3159/handling-dependencies-in-a-one-assembly#comment19</link><guid>http://ayende.com/3159/handling-dependencies-in-a-one-assembly#comment19</guid><pubDate>Sun, 24 Feb 2008 12:53:44 GMT</pubDate></item><item><title>Ayende Rahien commented on Handling dependencies in a one assembly</title><description>Andrey,
  
Rhino Mocks doesn't use internal.
  
It has a very rich API, but almost always, you are going through the well defined published interface (as opposed to the public interface).
  
If you need more, you can just add it.
  
It works very well.
  
</description><link>http://ayende.com/3159/handling-dependencies-in-a-one-assembly#comment18</link><guid>http://ayende.com/3159/handling-dependencies-in-a-one-assembly#comment18</guid><pubDate>Sun, 24 Feb 2008 08:48:10 GMT</pubDate></item><item><title>Andrey Shchekin commented on Handling dependencies in a one assembly</title><description>I always thought the most important point of building a library is making developers' life easier. I really like the simplicity of NMock where I have Expect which is a facade to the whole API. Opening the internals should mean that you at least regroup the classes so that the lesser used ones do not pollute more used namespaces.
  
  
And I almost never use private classes, these are just too messy to work with -- and also they are untestable without Reflection (as compared to internals).
</description><link>http://ayende.com/3159/handling-dependencies-in-a-one-assembly#comment17</link><guid>http://ayende.com/3159/handling-dependencies-in-a-one-assembly#comment17</guid><pubDate>Sun, 24 Feb 2008 07:53:46 GMT</pubDate></item><item><title>Ayende Rahien commented on Handling dependencies in a one assembly</title><description>I am not really concerned about scaring develpers.
  
If they can't handle a few more classes, they are welcome to go back to program in Basic on Dos 1.0, with ~ 25 commands or so for them to deal with.
  
  
I recognize the need for private classes, by all mean encapsulate using that. But internal is evil in frameworks
</description><link>http://ayende.com/3159/handling-dependencies-in-a-one-assembly#comment16</link><guid>http://ayende.com/3159/handling-dependencies-in-a-one-assembly#comment16</guid><pubDate>Sun, 24 Feb 2008 07:29:07 GMT</pubDate></item><item><title>Andrey Shchekin commented on Handling dependencies in a one assembly</title><description>I do not remember, but I think I already touched this point. When designing a library, you can just open all internal classes, but it is a lazy solution. The best solution is to prefer public over internal everywhere the functionality can not be accessed otherwise, and design accordingly.
  
  
So if I had SqlCommandSet I do not need SqlCommandSet.LocalCommand. I would never need ADP or Bid no matter what, opening these will just increase complexity. Opening everything without appropriate grouping will scare the hell out of new .Net developers.
</description><link>http://ayende.com/3159/handling-dependencies-in-a-one-assembly#comment15</link><guid>http://ayende.com/3159/handling-dependencies-in-a-one-assembly#comment15</guid><pubDate>Sun, 24 Feb 2008 07:25:09 GMT</pubDate></item><item><title>Ayende Rahien commented on Handling dependencies in a one assembly</title><description>Andrey,
  
That assume that you own all the code, and can change it if you need to.
  
Take a look at the BCL and see how many times what you want is so close, but it is locked under internal keyword.
  
SqlCommandSet, WCF's CreateChannel(Type), LinqExpressionVisitor....
  
Those are just a few that comes to mind
</description><link>http://ayende.com/3159/handling-dependencies-in-a-one-assembly#comment14</link><guid>http://ayende.com/3159/handling-dependencies-in-a-one-assembly#comment14</guid><pubDate>Sun, 24 Feb 2008 01:07:09 GMT</pubDate></item><item><title>Andrey Shchekin commented on Handling dependencies in a one assembly</title><description>And I do not really understand why internals are bad. There are a lot of cases when using some lower-level code for functionality that is already provided by the higher-level one is more complex, more problematic, and can lead to code duplication. 
  
  
Now, the perfect developer instantly knows what classes/methods to use for his specific task. The real developers I worked with often choose what they found first, just because when they invent the way to use it, they stop searching.
  
  
And if code really wants to get some low-level functionality that is not currently available, it may mean that API got out of date and should be refactored. Or may be the code wants some common stuff other code uses. Then this stuff should probably be moved to the common area, not used from where it was originally.
  
  
For example I may have a folder in my project named QuerySupport that has some classes used only by queries. Let's think you want to reuse one class of these. It probably means that this class should not be in QuerySupport folder/namespace anymore. Of course, I could have put all these classes to less specific place at the very beginning, but then I will make a mess of my solution.
</description><link>http://ayende.com/3159/handling-dependencies-in-a-one-assembly#comment12</link><guid>http://ayende.com/3159/handling-dependencies-in-a-one-assembly#comment12</guid><pubDate>Sun, 24 Feb 2008 00:08:50 GMT</pubDate></item><item><title>Andrey Shchekin commented on Handling dependencies in a one assembly</title><description>And I do not really understand why internals are bad. There are a lot of cases when using some lower-level code for functionality that is already provided by the higher-level one is more complex, more problematic, and can lead to code duplication. 
  
  
Now, the perfect developer instantly knows what classes/methods to use for his specific task. The real developers I worked with often choose what they found first, just because when they invent the way to use it, they stop searching.
  
  
And if code really wants to get some low-level functionality that is not currently available, it may mean that API got out of date and should be refactored. Or may be the code wants some common stuff other code uses. Then this stuff should probably be moved to the common area, not used from where it was originally.
  
  
For example I may have a folder in my project named QuerySupport that has some classes used only by queries. Let's think you want to reuse one class of these. It probably means that this class should not be in QuerySupport folder/namespace anymore. Of course, I could have put all these classes to less specific place at the very beginning, but then I will make a mess of my solution.
</description><link>http://ayende.com/3159/handling-dependencies-in-a-one-assembly#comment13</link><guid>http://ayende.com/3159/handling-dependencies-in-a-one-assembly#comment13</guid><pubDate>Sun, 24 Feb 2008 00:08:50 GMT</pubDate></item><item><title>Andrey Shchekin commented on Handling dependencies in a one assembly</title><description>Talking of internals, I sometimes want to kill API makers for using GetExportedTypes (Castle.BatchRegistration) or similar approaches (MbUnit). I have internal classes and public interfaces in most of my layers -- this reduces API complexity and makes right choice easier. I feel that not only the right solution should be easy -- the metasolution of choice between solutions should also be.
  
  
But the reason is less important -- the important thing is that external libraries should not have to be hacked and patched to find internals if I want to.
</description><link>http://ayende.com/3159/handling-dependencies-in-a-one-assembly#comment11</link><guid>http://ayende.com/3159/handling-dependencies-in-a-one-assembly#comment11</guid><pubDate>Sat, 23 Feb 2008 23:53:31 GMT</pubDate></item><item><title>Ayende Rahien commented on Handling dependencies in a one assembly</title><description>I used to work with a bunch of junior guys. 
  
You can bet that they run into the same issues as well, and you need only to rename a column once to show them why this is a really bad idea.
  
  
You need to introduce that to them, but that is all.
</description><link>http://ayende.com/3159/handling-dependencies-in-a-one-assembly#comment10</link><guid>http://ayende.com/3159/handling-dependencies-in-a-one-assembly#comment10</guid><pubDate>Sat, 23 Feb 2008 13:39:11 GMT</pubDate></item><item><title>Casey commented on Handling dependencies in a one assembly</title><description>&gt;&gt;&gt;Casey,
  
Not the way I do it. Just handling paging and ordering with this is a major issue.&lt;&lt;&lt;
  
  
  
Not the way you or I do it, but its still 100x easier ...  you really do get to work with the elite of develoeprs ... most .Net developers I meet actually think this is the *best* way to do it, not only the easiest ... :)
  
  
  
</description><link>http://ayende.com/3159/handling-dependencies-in-a-one-assembly#comment9</link><guid>http://ayende.com/3159/handling-dependencies-in-a-one-assembly#comment9</guid><pubDate>Sat, 23 Feb 2008 07:19:05 GMT</pubDate></item><item><title>Ayende Rahien commented on Handling dependencies in a one assembly</title><description>Casey,
  
Not the way I do it. Just handling paging and ordering with this is a major issue.
  
</description><link>http://ayende.com/3159/handling-dependencies-in-a-one-assembly#comment8</link><guid>http://ayende.com/3159/handling-dependencies-in-a-one-assembly#comment8</guid><pubDate>Sat, 23 Feb 2008 00:00:02 GMT</pubDate></item><item><title>Ayende Rahien commented on Handling dependencies in a one assembly</title><description>Johanatan,
  
Abolish internal methds, problem solved.
</description><link>http://ayende.com/3159/handling-dependencies-in-a-one-assembly#comment7</link><guid>http://ayende.com/3159/handling-dependencies-in-a-one-assembly#comment7</guid><pubDate>Fri, 22 Feb 2008 23:58:35 GMT</pubDate></item><item><title>Casey commented on Handling dependencies in a one assembly</title><description>&gt;&gt;&gt;And we shouldn't forget about Internal methods in our classes. Having one assembly for the application will make internal methods visible for the entire application&lt;&lt;&lt;&lt;
  
  
Don't get Oren started on Internal :)   
</description><link>http://ayende.com/3159/handling-dependencies-in-a-one-assembly#comment6</link><guid>http://ayende.com/3159/handling-dependencies-in-a-one-assembly#comment6</guid><pubDate>Fri, 22 Feb 2008 15:51:34 GMT</pubDate></item><item><title>Jonathan commented on Handling dependencies in a one assembly</title><description>And we shouldn't forget about Internal methods in our classes. Having one assembly for the application will make internal methods visible for the entire application.
</description><link>http://ayende.com/3159/handling-dependencies-in-a-one-assembly#comment5</link><guid>http://ayende.com/3159/handling-dependencies-in-a-one-assembly#comment5</guid><pubDate>Fri, 22 Feb 2008 15:33:28 GMT</pubDate></item><item><title>Colin Jack commented on Handling dependencies in a one assembly</title><description>I think it might be worth specifying what I think some of the advantages of multiple projects are:
  
  
 1) Explicit dependency management - Namespaces backed up by NDepend are probably an option, though not one I've tried. However at the moment projects are the obvious way of handling dependencies.
  
 2) Build Time - If done carefully you can lower the build time for particular pieces of the system (especially if you use multiple solutions).
  
 3) Modularization - If I mainly work in a Crm domain model and never go near the Finance aspects do I really want to see them in my project?
  
 4) Management - If you have one massive project then it's quite possible that you'll be working on two bits at once, such as Model and Web or Model and Services. I find that this can get painful when you have a whole lot of stuff in one project.
  
 5) Tests - If you have one big test project then its going to have a complex folder structure for a big app, again navigating around it will be hard as will switching from it to the appropriate part of the main project.
  
 6) Multiple applications - Obviously if you have multiple apps using the same model you will need to break it out.
  
  
Thats just been my experience though, and of course multiple projects have their own issues. Having said that I've worked with big projects and smaller projects and so far I prefer the latter.
</description><link>http://ayende.com/3159/handling-dependencies-in-a-one-assembly#comment4</link><guid>http://ayende.com/3159/handling-dependencies-in-a-one-assembly#comment4</guid><pubDate>Fri, 22 Feb 2008 14:41:06 GMT</pubDate></item><item><title>Colin Jack commented on Handling dependencies in a one assembly</title><description>"And as Udi said in the other thread... the first code review I do is to check the Refernces section and ask why XYZ is in there ... "
  
  
Yeah thats what we do too.
  
  
Having said that the namespace approach is also valid: 
  
  
http://www.theserverside.net/tt/articles/showarticle.tss?id=ControllingDependencies
  
  
I personally think that, with the way VS is currently structured, having multiple project and if necessary multiple solutions is a good way of working. Sure it increases overall build time and so on but there are other issues including complexity, if you have everything in one project then working within that project is quite likely to get unmanageable.
</description><link>http://ayende.com/3159/handling-dependencies-in-a-one-assembly#comment3</link><guid>http://ayende.com/3159/handling-dependencies-in-a-one-assembly#comment3</guid><pubDate>Fri, 22 Feb 2008 12:59:38 GMT</pubDate></item><item><title>Casey commented on Handling dependencies in a one assembly</title><description>It is still much easier to write "select * from table" in an ObjectDataSource and bind it than it is to write a view, a presenter, and a repository  :)
  
  
And as Udi said in the other thread... the first code review I do is to check the Refernces section and ask why XYZ is in there ...
</description><link>http://ayende.com/3159/handling-dependencies-in-a-one-assembly#comment2</link><guid>http://ayende.com/3159/handling-dependencies-in-a-one-assembly#comment2</guid><pubDate>Fri, 22 Feb 2008 12:13:58 GMT</pubDate></item><item><title>Dan commented on Handling dependencies in a one assembly</title><description>I prefer to have ( apart of default one assembly target ) a NAnt target that emits several assemblies for each logical layer and test the result.
  
As the logical layers are in separated folders it's easy stuff for &lt;csc /&gt; task, unless there is some WPF/... msbuild magic involved.
  
  
And having a solution with 30 or more projects is a really bad idea, you can't ignore the fact that Visual Studio performance suffers big time. 
</description><link>http://ayende.com/3159/handling-dependencies-in-a-one-assembly#comment1</link><guid>http://ayende.com/3159/handling-dependencies-in-a-one-assembly#comment1</guid><pubDate>Fri, 22 Feb 2008 10:57:18 GMT</pubDate></item></channel></rss>