Category Archives: Castle

New adventures under medium trust

Many web hosting companies only allow ASP.NET applications to run under medium trust. This has been a major drawback for Cuyahoga because it required full trust (or better: some libraries require full trust). This has already caused some nasty surprises when people deployed their site to the host to find out it would not run.

Well, I can finally say that Cuyahoga 2.0 will work under medium trust!

Castle DynamicProxy

Last week, someone mentioned on the Castle users list that DynamicProxy was supposed to work under medium trust and this immediately triggered me. DynamicProxy had always been the key part that prevented Cuyahoga, NHibernate, and lots of other software from running under medium trust because it generates assemblies on the fly and that’s not allowed (at least pre-NET 2.0 SP1).

So, I checked out a fresh version of the Castle trunk, built it with AllowPartiallyTrustedCallers and copied the assemblies to Cuyahoga that was set to run under medium trust.
Unfortunately, still no luck. The dreaded SecurityException showed its yellow screen, but instead of giving up immediately, I took a deep breath and started digging the DynamicProxy sources. The solution was a simple one: DynamicProxy calls AssemblyBuilder.DefineDynamicModule and used the overload that generates debug symbols. Changing that to not generate the debug symbols anymore made it work under medium trust! I send a patch to the Castle guys and lets hope it can be incorporated. This allows NHibernate to run under medium trust without turning off lazy-load on class mappings or using a special proxy generator.

One caveat: the Castle trunk requires .NET 3.5, so we can’t fix it for the 1.6.x branch of Cuyahoga which is .NET 2.0.

Lucene.Net

Second, Lucene.Net didn’t work under medium trust and boy, that was easy to fix: a single call was made to a relative file path, which is not allowed. Changed that to use the full path and it worked. Submitted a patch and I hope they will accept it.

Cuyahoga

So, with the libraries working under medium trust, I was ready to roll, at least I thought so. It appeared however that Cuyahoga also did some nasty things that are not allowed under medium trust, such as requesting a HttpModule instance from the appdomain and some file access outside the application root. Fortunately these were easy fixes and now I have everything working just fine under medium trust.

I think, I’ll leave medium trust turned on in the development version to signal issues in an early state.

Hidden jewels in the Castle stack: Transaction Services

In Cuyahoga, we’re using a lot of components from the Castle stack. Some of the most brilliant components are the transaction services combined with the automatic transaction facility.

With this post, I’m trying to bring some well-deserved attention to these undervalued components.

The Context

Today, I was working on management of sites. In Cuyahoga 2.0, every site has its own set of content folders and templates. Now when creating a new site, we have to perform the following steps:

  1. Save the new site object in the database;
  2. Create a folder structure for the new site;
  3. Copy the selected system template objects to the new site and save in the database;
  4. Copy the template files that belong to the copied template objects to the templates folder of the site.

All steps have to be completed before we can start management of the new site, like adding pages and custom templates. Obviously, you’d like this series of steps to be completed  in a single transaction, so when something goes wrong somewhere, we don’t end up with a broken site.

As you might have noticed, the transaction also includes file operations and we all have probably experienced situations where the database and the file system were out of sync because something went wrong, either in the database, or with the file system.

Enter Castle Transactions

Castle Transaction Services makes it possible to run any arbitrary piece of code within the scope of a transaction. Components that are called in a transaction can support those transactions by requesting the current transaction via a transaction manager. This makes it very easy to write your own components that are transaction-aware.

Transactional file operations: don’t let the database and file system go out of sync

For file operations, we created a simple service that performs common file operations like writing new files, copying files and creating folders. When performing an operation, the service checks if there is a current transaction and if so, the actual operation is delegated to a class that performs the actual transactional operation. An excerpt of our transactional fileservice:

public void CopyFile(string filePathToCopy, string directoryToCopyTo)
{
    ITransaction transaction = ObtainCurrentTransaction();
    if (transaction != null)
    {
        FileWriter fileWriter = new FileWriter(this._tempDir, transaction.Name);
        transaction.Enlist(fileWriter);
        fileWriter.CopyFile(filePathToCopy, directoryToCopyTo);
    }
    else
    {
        File.Copy(filePathToCopy, Path.Combine(directoryToCopyTo, Path.GetFileName(filePathToCopy)), true);
    }
}

In the example above, the FileWriter class performs the transactional file operations by implementing an IResource interface that has three methods: Start(), RollBack() and Commit(). The CopyFile() method copies the file to a temporary location. When the transaction manager commits the transaction, the Commit() method of the FileWriter is called and the file is copied from the temporary location to the actual location. RollBack() removes the temporary file.

The complete implementation of the file service can be found in Cuyahoga SVN at https://cuyahoga.svn.sourceforge.net/svnroot/cuyahoga/trunk/Core/Service/Files. Note that the implementation is very basic and there’s much room for improvement but it already saved us lots of time when we didn’t have to clean up the mess when something went wrong.

Automatic transactions

One of the really great features of the Castle transaction services is that you just have to decorate your method with an attribute and everything is executed within the context of a transaction:

[Transaction(TransactionMode.RequiresNew)]
public virtual void CreateSite(Site site, string siteDataRoot, IList<Template> templatesToCopy, string systemTemplatesDirectory)
{
    // 1. Save new site object in the database.
    ..

    // 2. Create site directories.
    ..

    // 3. Copy template objects to new site and save in database.
    ..

    // 4. Copy template files to site templates directory.
    ...
}