Contents tagged with Resharper

  • CodeStore - Part 3 of n (Cecil, Moq)

    This is the third part of the series on building CodeStore. In this blog post, I'll finish off the first user story which was

    1)  As a customer, I want to query the Assembly data in the database so that I can get metrics about the assembly.

     

    The story is further decomposed into two tasks:

     

    a)   Read Assembly Data

    b)   Store Assembly Data in SQLite using Nhibernate.

     

    We start with completing the unit test for AssemblyDataRepository. If you remember in Part II  that I changed the Nhibernate integration to use Castle Nhibernate repository and therefore passing in the ISessionManager to the repository classes.

     

    So, to test AssemblyDataRepository I'm going to mock ISessionManager to test the behaviour of the method.  As this project is about learning so I've decided to use Moq (http://code.google.com/p/moq/) as the mocking container. 

     

    Moq uses lambdas to set expectations which takes some practice to get used to. You can read more about Moq on Daniel Cazzulino blog (http://www.clariusconsulting.net/blogs/kzu/).

     

    So we start with a test for adding assembly data using the repository.

     

     

    It uses the same test flow as other testing (mocking) frameworks.

    1. Setup data
    2. Setup mocks, expectations
    3. Run SUT
    4. Verity the expectations

    Once the test is passed, we can check off the second task of the story. I can write few more tests but let's not worry about that for now. The next thing to look into is actually parsing the assembly and extracting the required information from assembly metadata. To read IL, I'm going to use Cecil which can be downloaded from http://www.mono-project.com/Cecil.

     

    The initial model for code analysis engine looks like this. (Please note that the following diagram is the snapshot taken at the end of this blog post)

     

    I started with CodeAnalysisEngine whose job is to ask the CodeAssemblyLoader to load the assembly and then pass it to CodeAssemblyParser to do the actual information extraction.

     

    Testing CodeAnalysisEngine:

     

     

    The first two statements create the mock objects to use in the actual call. The next line sets the expectation to load the provided assembly file. The implementation of the SUT:

     

     

    In the next test, I added the assembly parser in the constructor which prompts a change in the first test to take in another argument.

     

     

    And the implementation now calls the Parse method on the assembly parser.

     

     

    The next step is to unit test the CodeAssemblyLoader. This class is responsible for loading the assembly file using Cecil, so the test expects a call to Cecil's AssemblyFactory.GetAssembly method. Unfortunately AssemblyFactory.GetAssembly is a static call which makes it impossible to test. If it is Ruby then I can easily mock it but that's another thing :).

     

    And, here is the implementation of CodeAssemblyLoader class

     

     

    Testing CodeAssemblyParser is also not easy because of the same AssemblyFactory issue so I'm going to load the actual assembly but mock the repository to expect the add method.

     

     

    Line no. 17 is loading the actual assembly. Then I mocked the repository and set it to the assembly parser. In the end, I set the expectation and call the method to verify.  The Parse method internally calls the AddAssemblyData method with the assembly definition.

     

     

    So the unit tests are passing, I still need to implement the dependency injection configuration to run the application.

     

    Setting up Castle configuration for dependency injection:

     

    There are two different dependencies which we need to resolve here. First, CodeAnalysisEngine depends on the CodeAssemblyLoader and CodeAssemblyParser which it takes in as constructor arguments.

     

     

    Second, to resolve the dependency in assembly parser for assembly data repository which is a property.

     

     

    After configuring the dependencies, I can run the application select the TestCases.dll file which we created in part II.

     

     

    To confirm if it works by opening the codestore.db file in the database browser.

     

     

    Source Code: http://code.google.com/p/code-store/

     

    Conclusion:

    So, this completes the first story which is about storing the information about the assembly into the database. I also looked into interaction based testing and used the Moq framework to implement mocks inside the tests. The assembly parsing is then implemented using Cecil.

     

    As always, your suggestions and comments are always welcome to improve the project.

    Read more...

  • CodeStore - Part 2 of n (SQLite, NHibernate)

     So, in the last post, I started creating a new application using TreeSurgeon and added Castle Windsor and log4net support. In this post, I'm going to describe how I added the Nhibernate support and the Castle Nhibernate facility.

       

    User Stories:

    Because CodeStore is about storing metrics about an Assembly therefore I'm going to start by storing the assembly information. Therefore the first user story is:

     

    1) As a customer, I want to query the Assembly data in the database so that I can get metrics about the assembly.

       

      After breaking the story into tasks, we have:

    a) Read Assembly Data

    b) Store Assembly Data in SQLite using Nhibernate.

       

    Although we can start with any task, but in this scenario I'll go with the second task which is about setting up Nhibernate to store data in the SQLite database.

       

    Pre-Requisites:

    There are few things we need to download and setup before start coding.

  • Download SQLite ADO.NET Database Provider (http://sqlite.phxsoftware.com/). The good thing about this provider is that it embeds the sqlite database engine so you don't need any more dependencies.
  • Download SQLIte Database Browser to manage the database (http://sqlitebrowser.sourceforge.net/) but you can also use the native sqlite engine to manage the database from console.
  • Download NHibernate.
  •  

    Once we have the required dependencies, we can start by creating a new datastore. SQLite Database Browser allows you to create a new database but you'll have to create a temporary table so that it can save it in the file.

     

     

    Then I added a new class AssemblyData in our Core.Domain namespace.

     

     

    Once all the fields are defined, I generated all the properties using Resharper (Alt+Ins)

     

     

    It seems that Resharper doesn't generate the auto properties so you'll have to fix it (Ctrl + Enter).

     

     

    Or you can just type the auto properties without any help which may be the quickest option :).

     

    The next step is to create the nhibernate mappings file. When editing the mapping file, it is much better to add the nhibernate mappings schema to get intellisense in the IDE.

     

     

     

     

    The complete mapping file looks like this. The build action should be set to embedded resource.

     

    <?xml version="1.0" encoding="utf-8" ?>

    <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"

                       assembly="CodeStore.Core" namespace="CodeStore.Core.Domain">

      <class name="AssemblyData">

        <id name="Id">

          <generator class="guid"/>

        </id>

        <property name="Name"/>

        <property name="FullName"/>

        <property name="Version"/>

        <property name="EntryPoint"/>

      </class>

    </hibernate-mapping>

     

    As we have the domain class and the corresponding mapping file, we can configure the application to use Nhibernate. For that, I created a separate hibernate.cfg.xml file in the Core application with the following contents. The properties are self-explanatory and you can always learn more by looking into the Nhibernate documentation.

     

    <?xml version="1.0" encoding="utf-8" ?>

    <hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">

      <session-factory>

        <property name="connection.driver_class">NHibernate.Driver.SQLite20Driver</property>

        <property name="connection.connection_string">Data Source=E:\Code\CodeStore\data\codestore.db;Version=3;New=False;Compress=True;</property>

        <property name="dialect">NHibernate.Dialect.SQLiteDialect</property>

        <property name="query.substitutions">true=1;false=0</property>

        <property name="show_sql">true</property>

      </session-factory>

    </hibernate-configuration>

     

    To check whether the configuration is correct, I quickly wrote a test to generate the schema for the above domain model.

     

    [TestFixture]

    public class HibernateTest

    {

    [Test]

    public void CanExportSchema()

    {

                var cfg = new Configuration();

                cfg.Configure();

                cfg.AddAssembly(typeof(CodeStore.Core.Domain.AssemblyData).Assembly);

                new SchemaExport(cfg).Execute(false, true, false, false);

    }

    }

     

    The above code will generate the AssemblyData table in the database with the defined fields.

     

     

    So this is one approach to design  (domain driven design) where we started with our domain model and then generate the database in the end. The other side of it is data driven design where you can start with the database and generate your domain from these entities. By using the database, you can also generate the plumbing code for domain model (i.e. Mapping files and Domain classes) using some generation tool like MyGeneration or CodeSmith.

     

    Now, using the Repository pattern, I'm going to create a repository to save assembly data into the database.

     

     

    Although not TDD, but writing a test now.

     

     

    If the code looks familiar to you then you must have been to the excellent tutorial on this website.

     

    Currently we are using plain vanilla Nhibernate through the NHibernateHelper which is not a bad thing but there is Castle NHibernate facility that we can utilise and abstract the Nhibernate plumbing. To do so, there are two different types of integration styles (defined here) I'm using the second approach which looks more straight forward.

     

    The first thing is the change in configuration file.  The hibernate configuration is currently defined in a separate hibernate.cfg.xml file which I'm going to move into the app.config file inside the existing castle/facilities section.

     

     

    The second thing is to change the repository class to inject ISessionManager (link) in the constructor.

     

     

    And then you can use the data repository as:

     

     

    Source Code: http://code.google.com/p/code-store/ 

     

    Conclusion:

    In this blog post, we started with creating a database and the domain model for storing AssemblyData. In the next post, we are going to use mocks to test the repository.

     

    As always, comments and suggestions are most welcome to improve the project.

    Read more...

  • 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

       

      Setup:

      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.

       

       

      Code check-in:

      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

       

      Writing code:

      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");

      assemblyLoader.Load();

       

      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.

       

      <components>

            <component id="assemblyLoader" service="CodeStore.Core.ILoader, CodeStore.Core"

                      type="CodeStore.Core.CodeAssemblyLoader, CodeStore.Core">

            </component>

       </components>

       

      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.

       

       

      Source Code

       

      Conclusion:

      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.

    Read more...