Brett,
See inline.
Say the library A.dll file references System.Windows.Forms.dll and then
my EXE webform project also references System.Windows.Forms. The EXE
calls objects in the Forms namespace, namely to create its forms. No
calls have been made into the Forms namespace of A.dll.
There is no such thing as the "forms namespace of A.dll". I think that
what you are trying to say is that there are no calls made from types in
A.dll to System.Windows.Forms.dll, while there are calls from the EXE into
type in System.Windows.Forms.dll.
Assuming
System.Forms.Windows.dll is 500k loaded in memory and the data pages
are 64k each, does it currently looks like:
500k ("both" EXE and A.dll have load System.Forms.Windows.dll) and not
500k + 500k = 1000k
+ 64k (only the EXE has called into the Forms namespace)
No, if System.Windows.Forms.dll is a total of 500k, and types are used
from System.Windows.Forms.dll, then 500k is used. The total of 500 includes
the code and the data page. If the data page is 64k of the 500k, and there
is more than one app domain, (say two), then you have an additional 64k
being used by each app domain for the data page for the dll.
Good so far?
Now, the point behind this is: Would it be worth me removing the
System.Windows.Forms namespace from A.dll and putting it into a UI.dll?
For any non forms libraries that call A.dll, they will "have to" load
the Forms namespace right, since A.dll file references
System.Windows.Forms.dll? Since those libraries will never call into
the Forms namespace, loading the Forms namespace is a waste of memory.
Well, not necessarily. If types that are exposed by
System.Windows.Forms.dll are never called by the types in A.dll, then
System.Windows.Forms.dll is not loaded, unless some other type in another
assembly called into it, causing it to load.
You can set a reference to as many assemblies as you wish, but if you do
not access the types in that assembly in any way, then the loader will not
go through the trouble of loading the assembly.
500k - System.Windows.Forms.dll (A.dll is loaded by B.dll, non form
library)
+ 50k - A.dll (references Forms namespace)
+ 50k - B.dll
No, the total is 600k. Remember, your initial example is 500k for the
code and the data pages.
Isn't this a waste of 500k memory?
Well, it depends on what you mean by waste. In the scheme of things
today, I would say that 500k is not. However, System.Windows.Forms.dll is a
bit bigger than that (5MB+), and I would say THAT is a waste. Of course, in
the words of Depeche Mode, everything counts in large amounts, meaning, if
you load enough small dlls, you could have a problem.
On the other hand, if those same libraries are also going to be file
referenced by a winform app, what difference does it make if I leave
the Forms namespace in A.dll vs. putting it into UI.dll. The Forms
namespace is already loaded by the winform app and a data page is
created when a call is made from an assembly.
If System.Windows.Forms.dll is going to be referenced by another
assembly, then it doesn't matter.
The situation you want to avoid is exposing a function which is going to
be used often in a library where the rest of the library is not used.
A good example of this is the HttpContext class. It resides in
System.Web.dll. Usually, people want to find out if their app is running in
ASP.NET or not. So, you can go to HttpContext and access the static Current
property to see if there is an HttpContext. If it returns null, then you
are not running in ASP.NET.
Now, the thing is, to use this, if you are not in a web application (and
subsequently, would not use any of the functionality), then you end up
loading System.Web.dll JUST for determining if you are in ASP.NET, and you
end up loading 4MB+ into your app process/app domain space. That's a bit of
a waste, and what you want to avoid.
So, it's not really the reference to System.Windows.Forms.dll you have
to worry about, but rather, it is the other code that doesn't access it, and
the usage pattern. If you have to use System.Windows.Forms.dll, there is no
way around it, and just creating a reference to it is not going to impact in
any great way.
What you really have to look out for is exposing methods/types which are
used frequently, and then exposing a large code base in the same assembly
that is not used. If these types are not used too often, they are
participating in the code and data pages for the assembly and causing a
waste. They would be better off in another assembly.