Wednesday, July 16, 2008 5:27 PM
CodeStore - Part 1 of n (TreeSurgeon, Castle Windsor, Log4net)
What is CodeStore?
The idea behind CodeStore is to extract information about .NET assembly and store it in a database. One we have the data, we should be able to run standard SQL queries on the data store. Although, I'm planning to develop a WPF project to show some visualisation but let's see how it'll go.
So why CodeStore?
I needed a pet project as it's been some time from my last one. And I get more into Ruby and Java, this gives me an excuse to keep up my .NET skills. This is also an experiment to maintain a running project diary on this blog.
Tools to use:
Nhibernate: data access
Castle Windsor: application plumbing
Log4Net: logging (link)
... And many more
I started with setting up our development environment and one thing that proved very useful to me in the past is TreeSurgeon (http://www.codeplex.com/treesurgeon). TreeSurgeon is an excellent tool to generate your development tree. It definitely saved a lot of time at the start of the project.
Once the solution is generated, we can quickly check if the build is working.
Then I created a project on google project hosting which is available at http://code.google.com/p/code-store/.
I used TortoiseSVN (http://tortoisesvn.tigris.org/) to import the project and AnkhSVN (http://ankhsvn.open.collab.net/) for Visual Studio integration.
To ignore certain files, I've also setup the following pattern into TortoiseSVN global ignore pattern. (TortoiseSVN->Settings->General)
bin */bin obj */obj *.suo _ReSharper.* *.resharper *.resharper.user *.user
Now we can start plugging in Castle Windsor and setup the configuration to inject a simple class. To do so, I added the three castle dependencies into the CodeStoreConsole project.
And then using the following code inside Main() to resolve CodeAssemblyLoader.
var container = new WindsorContainer(new XmlInterpreter())
var assemblyLoader = container.Resolve<ILoader>("assemblyLoader");
As you can see, it is using WindsorContainer which is used to read the configuration file and resolve the components from the configuration. And the configuration looks like this.
<component id="assemblyLoader" service="CodeStore.Core.ILoader, CodeStore.Core"
You can view the complete application configuration file here. Here is the output when the application is executed.
At the moment, ILoader.Load() takes no argument, but we are going to change it so that it'll take in a file name. The target assembly is selected using the FileOpenDialog. This is a very common behaviour that I use so I think it would be better if I can put that in ReSharper Live Templates.
Now, I can use it using the shortcut.
After the code to open file, I added a new project in our solution which will be the target test case for the code analysis engine.
Now, when the application is executed, we'll see that the file is successfully selected.
At the moment, I'm using Console.Writeline to print the output which is not ideal so I'm going to replace it with log4net.
One way to add log4net is to directly add it in your code (like I described in http://weblogs.asp.net/nleghari/articles/easylog.aspx) but there is also Castle Logging facility which makes it possible to abstract the logging engine (although you can also do this quite easily).
One that topic, I found a very useful blog post by Casey Charlton about adding log4net with Castle factilities . In the end, I did it a little differently by extracting the Logger into its own class to avoid using properties in every method. The output generated in the log file is shown below.
Although I don't have anything to show to the client but we covered starting a new project using TreeSurgeon and then adding support for Castle Windsor and log4net. In the next post, I'll look into Nhibernate to create the domain model and the database in SQLite.
As always, any suggestions or comments are most welcome in order to improve the application.