<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Martijn Boland &#187; Castle</title>
	<atom:link href="http://blogs.taiga.nl/martijn/tag/castle/feed/" rel="self" type="application/rss+xml" />
	<link>http://blogs.taiga.nl/martijn</link>
	<description>New adventures in .NET</description>
	<lastBuildDate>Tue, 27 Apr 2010 20:51:13 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Cuyahoga 2.0 Alpha released</title>
		<link>http://blogs.taiga.nl/martijn/2009/12/12/cuyahoga-2-0-alpha-released/</link>
		<comments>http://blogs.taiga.nl/martijn/2009/12/12/cuyahoga-2-0-alpha-released/#comments</comments>
		<pubDate>Sat, 12 Dec 2009 15:32:51 +0000</pubDate>
		<dc:creator>martijn</dc:creator>
				<category><![CDATA[Cuyahoga]]></category>
		<category><![CDATA[ASP.NET MVC]]></category>
		<category><![CDATA[Castle]]></category>
		<category><![CDATA[CMS]]></category>
		<category><![CDATA[NHibernate]]></category>

		<guid isPermaLink="false">http://blogs.taiga.nl/martijn/2009/12/12/cuyahoga-2-0-alpha-released/</guid>
		<description><![CDATA[Just a little post to let you know that I released the first Alpha of the next generation of the Cuyahoga CMS yesterday. For the people who don’t know Cuyahoga: it’s a .NET CMS that uses lots of Open Source components like NHibernate, Castle Windsor and Lucene.NET. Although not as polished as Umbraco or Dotnetnuke, [...]]]></description>
			<content:encoded><![CDATA[<p>Just a little post to let you know that I released the first Alpha of the next generation of the <a href="http://cuyahoga-project.org">Cuyahoga</a> CMS yesterday. For the people who don’t know Cuyahoga: it’s a .NET CMS that uses lots of Open Source components like NHibernate, Castle Windsor and Lucene.NET. Although not as polished as <a href="http://umbraco.org" target="_blank">Umbraco</a> or <a href="http://www.dotnetnuke.com" target="_blank">Dotnetnuke</a>, I think it still shines when doing custom module and template development.</p>
<p>Development has been a long journey. Already back in 2006 we started development for the 2.0 version. In that time most of the work was done by Max Gaerber. He did a fantastic job in the design of the generic handling of content items.</p>
<p>Then somewhere in 2007 we started the new admin with Castle Monorail, did a spike with the first ASP.NET MVC, changed back to Monorail and finally changed to ASP.NET MVC again. The switch from ASP.NET WebForms to MVC for the site admin allowed us to do some pretty advanced AJAX stuff. The result is still a little rough around the edges, but it’s usable for experimental purposes. </p>
<p>Download it at <a title="http://sourceforge.net/projects/cuyahoga/files/" href="http://sourceforge.net/projects/cuyahoga/files/">http://sourceforge.net/projects/cuyahoga/files/</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.taiga.nl/martijn/2009/12/12/cuyahoga-2-0-alpha-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Entity Framework 4.0: a fresh start (with demo application)</title>
		<link>http://blogs.taiga.nl/martijn/2009/11/22/entity-framework-4-0-a-fresh-start-with-demo-application/</link>
		<comments>http://blogs.taiga.nl/martijn/2009/11/22/entity-framework-4-0-a-fresh-start-with-demo-application/#comments</comments>
		<pubDate>Sun, 22 Nov 2009 21:31:42 +0000</pubDate>
		<dc:creator>martijn</dc:creator>
				<category><![CDATA[O/R mapping]]></category>
		<category><![CDATA[ASP.NET MVC]]></category>
		<category><![CDATA[Castle]]></category>
		<category><![CDATA[Entity Framework]]></category>

		<guid isPermaLink="false">http://blogs.taiga.nl/martijn/2009/11/22/entity-framework-4-0-a-fresh-start-with-demo-application/</guid>
		<description><![CDATA[Edited 2009-11-26: removed EF4 Feature CTP from demo package and added some code examples. So, Entity Framework 1.0 pretty much sucks (compared to alternatives), but I’m glad to see that things have improved a lot in version 4.0 (we’ll call that EF4 from now). To see how the improvements work out, I did a quick [...]]]></description>
			<content:encoded><![CDATA[<p>Edited 2009-11-26: removed EF4 Feature CTP from demo package and added some code examples.</p>
<p>So, <a href="http://blogs.taiga.nl/martijn/2009/09/24/one-year-after-the-entity-framework-vote-of-no-confidence/">Entity Framework 1.0 pretty much sucks</a> (compared to alternatives), but I’m glad to see that things have improved a lot in version 4.0 (we’ll call that EF4 from now). To see how the improvements work out, I did a quick <a href="http://blogs.taiga.nl/martijn/wp-content/uploads/EF4Demo.zip" target="_blank">spike</a> that also gave me the opportunity to test some new ASP.NET MVC 2 features that I might blog about later.</p>
<h3>What’s in it?</h3>
<ul>
<li>Entity Framework 4 with POCO entity objects and <a href="http://blogs.msdn.com/efdesign/archive/2009/10/12/code-only-further-enhancements.aspx" target="_blank">code-only configuration</a> (no edmx);</li>
<li>Data access abstracted via repository interfaces;</li>
<li>ASP.NET 2 MVC for the UI;</li>
<li>Validation with Data Annotations;</li>
<li>Castle Windsor IoC container to wire the various components together;</li>
</ul>
<h3>EF4 POCO</h3>
<p>In EF4, it’s now possible to use entity classes that don’t have to inherit from EntityObject. This allows for better testability and separation of concerns. This is how an entity looks in the demo:</p>
<pre class="brush: csharp;">public class Course
{
    public virtual int Id { get; set; }

    [Required(ErrorMessage="Course title is required")]
    public virtual string Title { get; set; }

    [Required(ErrorMessage = "Price is required")]
    [DataType(DataType.Currency)]
    [Range(10.00, double.MaxValue, ErrorMessage="The minimum price is {1}")]
    public virtual decimal Price { get; set; }

    public virtual ISet&lt;Schedule&gt; Schedules { get; set; }

    public Course()
    {
        this.Schedules = new HashSet&lt;Schedule&gt;();
    }
}</pre>
<p>Note that all properties are marked virtual. This allows EF4 to do some magic with run-time proxy generation to allow lazy loading and change notification.</p>
<p>Also note that we can now easily add validation attributes (in this case from Sytem.ComponentModel.DataAnnotations). We don’t have to use those <a href="http://ayende.com/Blog/archive/2009/05/04/the-buddy-classes-are-drowning-dry.aspx" target="_blank">dreadful ‘buddy classes’</a> anymore to hold the meta-data.</p>
<h3>Code-only configuration</h3>
<p>EF4 now allows model-first design from the VS 2010 designer, but it can still get awkward with a lot of entities. Fortunately, the <a href="http://www.microsoft.com/downloads/details.aspx?displaylang=en&amp;FamilyID=13fdfce4-7f92-438f-8058-b5b4041d0f01" target="_blank">EF4 Feature CTP</a> makes it possible <a href="http://blogs.msdn.com/efdesign/archive/2009/10/12/code-only-further-enhancements.aspx" target="_blank">to do everything in code</a>.</p>
<p>So you now just create your POCO entity and add a mapping class that replaces the edmx designer:</p>
<pre class="brush: csharp;">public class CourseMapping : EntityConfiguration&lt;Course&gt;
{
    public CourseMapping()
    {
        HasKey(c =&gt; c.Id);
        Property(c =&gt; c.Id).IsIdentity();
        MapSingleType(c =&gt; new
        {
            courseid = c.Id,
            title = c.Title,
            price = c.Price
        }).ToTable("course");
        Property(c =&gt; c.Price).HasStoreType("money").HasPrecision(19, 4);
    }
}</pre>
<p>Looks remarkably similar to <a href="http://wiki.fluentnhibernate.org/Main_Page" target="_blank">Fluent NHibernate</a>, doesn’t it? <img src='http://blogs.taiga.nl/martijn/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>I’m not sure if this is the most optimal way to define the mapping, but it works. In the demo, there is a class CoursesContextBuilder that wraps the ContextBuilder from the EF4 Feature CTP where the mappings are added. It also serves as a factory for new ObjectContext instances () :</p>
<pre class="brush: csharp;">public class CoursesContextBuilder
{
    private ContextBuilder&lt;ObjectContext&gt; _builder;
    private string _defaultConnectionString;

    public CoursesContextBuilder(string defaultConnectionString)
    {
        this._defaultConnectionString = defaultConnectionString;
        this._builder = new ContextBuilder&lt;ObjectContext&gt;();
        ConfigureMappings();
    }

    private void ConfigureMappings()
    {
        _builder.Configurations.Add(new TeacherMapping());
        _builder.Configurations.Add(new CourseMapping());
        _builder.Configurations.Add(new ScheduleMapping());
    }

    public ObjectContext GetContext()
    {
        return GetContext(_defaultConnectionString);
    }

    public ObjectContext GetContext(string connectionString)
    {
        var context = _builder.Create(GetConnection(connectionString));
        context.ContextOptions.LazyLoadingEnabled = true;
        return context;
    }

    private DbConnection GetConnection(string connectionString)
    {
        // Hardcoded to SqlConnection for this demo.
        return new SqlConnection(connectionString);
    }
}</pre>
<p>That’s all we need to get EF4 working. In theory, we can now do everything with the POCO classes and the ObjectContext that comes from the CoursesContextBuilder, but of course if we would use it this way, we are directly tied to EF again and there goes away our testability.</p>
<h3>Repository implementation</h3>
<p>To make sure our application code isn’t tied to EF directly, data access goes through Repository interfaces. In the demo app you can find a generic IRepository&lt;T&gt; interface that is implemented by an EfRepository&lt;T&gt; class. The EfRepository implementation uses the EF ObjectContext to perform queries and so on. Note that we added an extra IContextManager interface that the EfRepository depends on. The IContextManager is responsible for managing the lifetime of the ObjectContext that is obtained from the ContextBuilder. This way, the repository implementations don’t have to worry about creating and disposing ObjectContext instances. It’s just always always available.All specific Repository interfaces inherit from IRepository&lt;T&gt; and the specific implementations inherit from EfRepository&lt;T&gt;.</p>
<pre class="brush: csharp;">public interface ICourseRepository : IRepository&lt;Course&gt;
{
    void DeleteCourseWithSchedule(Course course);
    Ef4Poco.Domain.Course GetCourseWithSchedulesAndTeachers(int courseId);
    void RemoveScheduleFromCourse(Schedule schedule, Course course);
}</pre>
<pre class="brush: csharp;">/// &lt;summary&gt;
/// Course-specific repository.
/// &lt;/summary&gt;
public class CourseRepository : EfRepository&lt;Course&gt;, ICourseRepository
{
    public CourseRepository(IContextManager contextManager)
        : base(contextManager)
    { }

    public Course GetCourseWithSchedulesAndTeachers(int courseId)
    {
        // Wouldn't it be nice to have strong-typed includes?
        var query = from c in ObjectSet.Include("Schedules").Include("Schedules.Teacher")
                    where c.Id == courseId
                    select c;
        return query.Single();
    }

    public void RemoveScheduleFromCourse(Schedule schedule, Course course)
    {
        course.Schedules.Remove(schedule);
        CurrentObjectContext.DeleteObject(schedule);
        CurrentObjectContext.SaveChanges();
    }

    public void DeleteCourseWithSchedule(Course course)
    {
        // Howto configure cascade delete via code? This is a little cumbersome.
        var schedules = new List&lt;Schedule&gt;(course.Schedules);
        foreach (var schedule in schedules)
        {
            CurrentObjectContext.DeleteObject(schedule);
        }
        CurrentObjectContext.DeleteObject(course);
        CurrentObjectContext.SaveChanges();
    }
}</pre>
<h3>Consuming the data access interfaces</h3>
<p>Now we have our data access interfaces in place, it’s time for consuming. This is plain simple. Below is an example of how a controller in the ASP.NET MVC app in the demo uses the interfaces:</p>
<pre class="brush: csharp;">public class TeachersController : Controller
{
    private ITeacherRepository _teacherRepository;

    public TeachersController(ITeacherRepository teacherRepository)
    {
        _teacherRepository = teacherRepository;
    }

    public ActionResult Index()
    {
        var teachers = _teacherRepository.Find().OrderBy(t =&gt; t.Name);
        return View(teachers);
    }

    [...snip other methods]
}</pre>
<h3>The demo app</h3>
<p>You can<a href="http://blogs.taiga.nl/martijn/wp-content/uploads/EF4Demo.zip" target="_blank"> download the demo</a> to see what’s possible. It’s by no means a best practices example. Just a spike to test out various new technologies.</p>
<p>To run the demo, you’ll need Visual Studio 2010 Beta 2, <a href="http://www.microsoft.com/downloads/details.aspx?displaylang=en&amp;FamilyID=13fdfce4-7f92-438f-8058-b5b4041d0f01" target="_blank">the latest EF4 Feature CTP</a> and SQL Server (Express).</p>
<p>Both, the web and the test project have a connection string in the config file that defaults to the .\SQLEXPRESS instance. Change that if you want to use a different instance. The database name doesn’t matter because a new database will be created the first time you run the application. Note that the reference to the EF4 feature CTP (Microsoft.Data.Entity.CTP.dll) points to C:\Program Files (x86)\Microsoft ADO.NET Entity Framework Feature CTP2\Binaries. On 32 bit machines, you’ll probably have to change that to C:\Program Files\…</p>
<h3>Some observations</h3>
<ul>
<li>Entity Framework 4.0 is much, much better than version 1.0, especially for a model-first approach;</li>
<li>It’s not on par yet with <a href="http://nhforge.org" target="_blank">NHibernate</a> feature-wise (for example, I really miss cascade settings). Given the choice, I’d still opt for NHibernate, but it’s not a bad product anymore and I&#8217;d prefer it over LINQ to SQL at this time.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blogs.taiga.nl/martijn/2009/11/22/entity-framework-4-0-a-fresh-start-with-demo-application/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>New adventures under medium trust</title>
		<link>http://blogs.taiga.nl/martijn/2009/06/24/new-adventures-under-medium-trust/</link>
		<comments>http://blogs.taiga.nl/martijn/2009/06/24/new-adventures-under-medium-trust/#comments</comments>
		<pubDate>Wed, 24 Jun 2009 12:55:33 +0000</pubDate>
		<dc:creator>martijn</dc:creator>
				<category><![CDATA[Castle]]></category>
		<category><![CDATA[Cuyahoga]]></category>
		<category><![CDATA[Lucene.Net]]></category>
		<category><![CDATA[Medium Trust]]></category>
		<category><![CDATA[NHibernate]]></category>

		<guid isPermaLink="false">http://blogs.taiga.nl/martijn/2009/06/24/new-adventures-under-medium-trust/</guid>
		<description><![CDATA[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. [...]]]></description>
			<content:encoded><![CDATA[<p>Many web hosting companies only allow ASP.NET applications to run under medium trust. This has been a major drawback for <a href="http://cuyahoga-project.org">Cuyahoga</a> 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.</p>
<p>Well, I can finally say that Cuyahoga 2.0 will work under medium trust!</p>
<h3>Castle DynamicProxy</h3>
<p>Last week, someone mentioned on the <a href="http://castle-project.org" target="_blank">Castle</a> <a href="http://groups.google.com/group/castle-project-users" target="_blank">users list</a> that <a href="http://www.castleproject.org/dynamicproxy/index.html" target="_blank">DynamicProxy</a> was supposed to work under medium trust and this immediately triggered me. DynamicProxy had always been the key part that prevented Cuyahoga, <a href="http://nhforge.org/Default.aspx" target="_blank">NHibernate</a>, 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).</p>
<p>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.    <br />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 <a href="http://msdn.microsoft.com/en-us/library/system.reflection.emit.assemblybuilder.definedynamicmodule.aspx" target="_blank">AssemblyBuilder.DefineDynamicModule</a> 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 <a href="http://nhforge.org/wikis/howtonh/run-in-medium-trust.aspx" target="_blank">lazy-load on class mappings</a> or using a special <a href="http://blechie.com/WPierce/archive/2008/02/17/Lazy-Loading-with-nHibernate-Under-Medium-Trust.aspx" target="_blank">proxy generator</a>.</p>
<p>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. </p>
<h3>Lucene.Net</h3>
<p>Second, <a href="http://incubator.apache.org/lucene.net/" target="_blank">Lucene.Net</a> 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. <a href="http://issues.apache.org/jira/browse/LUCENENET-169" target="_blank">Submitted a patch</a> and I hope they will accept it.</p>
<h3></h3>
<h3>Cuyahoga</h3>
<p>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.</p>
<p>I think, I’ll leave medium trust turned on in the development version to signal issues in an early state.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.taiga.nl/martijn/2009/06/24/new-adventures-under-medium-trust/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Hidden jewels in the Castle stack: Transaction Services</title>
		<link>http://blogs.taiga.nl/martijn/2008/12/03/hidden-jewels-in-the-castle-stack-transaction-services/</link>
		<comments>http://blogs.taiga.nl/martijn/2008/12/03/hidden-jewels-in-the-castle-stack-transaction-services/#comments</comments>
		<pubDate>Wed, 03 Dec 2008 17:30:48 +0000</pubDate>
		<dc:creator>martijn</dc:creator>
				<category><![CDATA[Castle]]></category>
		<category><![CDATA[Cuyahoga]]></category>
		<category><![CDATA[Transactions]]></category>

		<guid isPermaLink="false">http://blogs.taiga.nl/martijn/archive/2008/12/03/hidden-jewels-in-the-castle-stack-transaction-services.aspx</guid>
		<description><![CDATA[In Cuyahoga, we&#8217;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&#8217;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, [...]]]></description>
			<content:encoded><![CDATA[<p>In <a href="http://cuyahoga-project.org" target="_blank">Cuyahoga</a>, we&#8217;re using a lot of components from the <a href="http://www.castleproject.org/" target="_blank">Castle</a> stack. Some of the most brilliant components are the <a href="http://www.jroller.com/hammett/entry/the_joys_of_castle_services" target="_blank">transaction services</a> combined with the <a href="http://www.castleproject.org/container/facilities/trunk/atm/index.html" target="_blank">automatic transaction facility</a>.</p>
<p>With this post, I&#8217;m trying to bring some well-deserved attention to these undervalued components.</p>
<h3>The Context</h3>
<p>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:</p>
<ol>
<li>Save the new site object in the database;</li>
<li>Create a folder structure for the new site;</li>
<li>Copy the selected system template objects to the new site and save in the database;</li>
<li>Copy the template files that belong to the copied template objects to the templates folder of the site.</li>
</ol>
<p>All steps have to be completed before we can start management of the new site, like adding pages and custom templates. Obviously, you&#8217;d like this series of steps to be completed  in a single transaction, so when something goes wrong somewhere, we don&#8217;t end up with a broken site.</p>
<p>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.</p>
<h3>Enter Castle Transactions</h3>
<p>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.</p>
<h3>Transactional file operations: don&#8217;t let the database and file system go out of sync</h3>
<p>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:</p>
<div style="border: 1px solid gray; margin: 20px 0px 10px; padding: 4px; overflow: auto; font-size: 8pt; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">
<div style="border-style: none; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"><span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> CopyFile(<span style="color: #0000ff">string</span> filePathToCopy, <span style="color: #0000ff">string</span> directoryToCopyTo)</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">{</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    ITransaction transaction = ObtainCurrentTransaction();</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">    <span style="color: #0000ff">if</span> (transaction != <span style="color: #0000ff">null</span>)</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    {</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">        FileWriter fileWriter = <span style="color: #0000ff">new</span> FileWriter(<span style="color: #0000ff">this</span>._tempDir, transaction.Name);</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">        transaction.Enlist(fileWriter);</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">        fileWriter.CopyFile(filePathToCopy, directoryToCopyTo);</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    }</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">    <span style="color: #0000ff">else</span></pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    {</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">        File.Copy(filePathToCopy, Path.Combine(directoryToCopyTo, Path.GetFileName(filePathToCopy)), <span style="color: #0000ff">true</span>);</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    }</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">}</pre>
</div>
</div>
<p>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.</p>
<p>The complete implementation of the file service can be found in Cuyahoga SVN at <a href="https://cuyahoga.svn.sourceforge.net/svnroot/cuyahoga/trunk/Core/Service/Files">https://cuyahoga.svn.sourceforge.net/svnroot/cuyahoga/trunk/Core/Service/Files</a>. Note that the implementation is very basic and there&#8217;s much room for improvement but it already saved us lots of time when we didn&#8217;t have to clean up the mess when something went wrong.</p>
<h3>Automatic transactions</h3>
<p>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:</p>
<div style="border: 1px solid gray; margin: 20px 0px 10px; padding: 4px; overflow: auto; font-size: 8pt; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">
<div style="border-style: none; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">[Transaction(TransactionMode.RequiresNew)]</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"><span style="color: #0000ff">public</span> <span style="color: #0000ff">virtual</span> <span style="color: #0000ff">void</span> CreateSite(Site site, <span style="color: #0000ff">string</span> siteDataRoot, IList&lt;Template&gt; templatesToCopy, <span style="color: #0000ff">string</span> systemTemplatesDirectory)</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">{</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">    <span style="color: #008000">// 1. Save new site object in the database.</span></pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    ..</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"></pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    <span style="color: #008000">// 2. Create site directories.</span></pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">    ..</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"></pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">    <span style="color: #008000">// 3. Copy template objects to new site and save in database.</span></pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    ..</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"></pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    <span style="color: #008000">// 4. Copy template files to site templates directory.</span></pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">    ...</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">}</pre>
</div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blogs.taiga.nl/martijn/2008/12/03/hidden-jewels-in-the-castle-stack-transaction-services/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
