Thank you very much for you appreciation. I had worked on documentation generator based on Mono.Cecil, something like NDoc, but much more complex, unfortunately I hadn't enough time to continue development of my project. It is good job, but still, it leaves much, much to be desired, it does not have any documentation so there is no possibility to publish in the web what I already did. But in the future, I certainly finish this project .
You may ask why not to use standard, built-in reflection engine (System.Reflection), the answer is simple, if you once load an assembly to an application domain you couldn't unload the assembly when you are finished, of course, you can create separate application domain load an assembly to it, and unload whole application domain, but this requires inheriting from MarshalByRefObject Class[^] when sending data across domains and this creates horrible bottleneck .
Mono.Cecil is superb library but it also has some drawbacks, the key is that it consumes pretty much memory (for mscorlib it is around 20MB), this is problem because, my documentation generator is built on a different philosophy, tools such as Sandcastle, first stores data gathered from reflection, then merges it with user comments and MSDN documentation, my project just loads all assemblies to memory, sorts namespaces and types within them, and then creates documentation - without saving any reflection data to file, this makes documentation generating very fast, but it comes at a cost. When you have 5-10 big assemblies being documented there is no problem, but if each of these assemblies references another 5 assemblies - they also must be loaded in order to document members from base classes. That makes a serious problem, memory consumption can be huge. I've removed some code from Cecil that was responsible for handling method's body, but in fact, it didn't help too much. I have some ideas to hop-over this problem, but currently I don't have enough time.
I have just seen your second article. Now I know what you were up to. I am using Mono Cecil also for some tool to check for API changes. My approach is different from yours in the way that I am loading only one assembly at a time into memory and try not to resolve the base types declared in other assemblies. It limits of course the ability to gather related information. There should be ways to unload assemblies when they are no longer needed. The easiest would be with a memory profiler to look where the objects are rooted to let the GC do its work.
This is an option, but from my point of view the best way is to store reflection data obtained by Mono.Cecil in some serverless database, such as SQLite. Then objects would be constructed only when necessary, with complex types loaded on-demand, good design of table/indexes, and caching already constructed instances, this solution would be pretty fast. Unfortunately, as far as I know, NHibernate doesn't support SQLite database dialect, and ADO.NET Entity Framework is rather young and immature, moreover it is widely criticised for lack of lazy-initialization, so the only one option is to create O/R mapping code manually and using LINQ to SQLite.
I am not sure if you really need a database. NDepends for example does store all the data as XML files which tend also to become very big and memory hungry. The all in memory approach does not scale for big projects with several hundreds up to thouands of assemblies. I would make the resolution process in passes. First pass read all assemblies one by one and store the base classes and interface dependencies for all types. The next pass can then build uppon the knowledge and load only on assembly at a time and load also the ones for the needed types. Suck the data out and make sure all the Mono Cecil data is ready to be GC collected. This way a rather slim system could be done. If you like you could store the type relationships in an XML index file just for fun but do not fall into the trap to store the dependencies as XML nodes since they are rather memory hungry.
This would be good solution, if documentation were generated assembly by assembly, rather than namespace by namespace - as my documentation generator does and as MSDN class reference for .NET is arranged. Since many assemblies can contain types which reside in the same namespace, there are chances that different assemblies would be constantly loaded and unloaded, when documenting a single namespace. Let's consider the following example, we have two assembies: A and B, the assembly A has TypeA and TypeC class, the assembly B has TypeB and TypeD class, all are members of MyNamespace namespace, below you can see what would happen if we wanted to generate documentation for this namespace assuming that members of the namespace are sorted ascending:
1. Analyze all assemblies to determine in what order they will be loaded and unloaded.
2. Load assembly A + reference assemblies.
3. Document members of namespace MyNamespace (TypeA class).
4. Unload assembly A + referenced assemblies.
5. Load assembly B + referenced assemblies.
6. Document members of namespace MyNamespace (TypeB class).
7. Unload assembly B + referenced assemblies.
8. Load assembly A + referenced assemblies.
9. Document member of namespace MyNamespace (TypeC class).
10. Unload assembly A + referenced assemblies.
11. Load asssembly B + referenced assemblies.
12. Document members of namespace MyNamespace (TypeD class).
13. Unload assembly B + referenced assemblies.
Many namespaces are divided between two or more assemblies, as you can see above delays in loading/unloading assemblies would seriously lengthen the time of generating documentation. I want to let user choose how documentation is arranged (namespaces as a root or assemblies as a root), so this solution will not satisfy me either. Anyhow, thanks for your tips.
Thank you. No I was not member of soviet union , Poland was part of soviet union till 1988. I put "formerly member of soviet union" because most readers of CodeProject are americans, in states, still some people don't know that Poland is now independent country with free-market economy.
Yes, you are right, theoretically Poland was not member of soviet union, but Poland along with other countries and Russia formed the Eastern Block, countries that were members of it had no influence on any key decisions, each country in Eastern Block has its own so-called secretary, but economy and army was controlled by the leader of the soviet union. In fact you are right, I have removed doubtful element from my CP profile, it was deceptive.
No, no, I don't feel offended, I was misunderstood, I wanted to clarify this issue to others too, because my sister was in USA two years ago and she told me that some people asked her whether Poland is still in soviet union, or event, whether Poland is in Russia
Last Visit: 31-Dec-99 19:00 Last Update: 28-Feb-24 9:30