Click or drag to resize

EditFileManager Class

Represents a resource manager which edits an existing file when a transaction is successfully committed.
Inheritance Hierarchy

Namespace:  Novacta.Transactions.IO
Assembly:  Novacta.Transactions.IO (in Novacta.Transactions.IO.dll) Version: 1.0.0
Syntax
public abstract class EditFileManager : FileManager

The EditFileManager type exposes the following members.

Constructors
  NameDescription
Public methodEditFileManager
Initializes a new instance of the EditFileManager class.
Top
Properties
  NameDescription
Public propertyManagedFileStream
Provides the stream for the managed file.
(Inherited from FileManager.)
Top
Methods
  NameDescription
Public methodCommit
Notifies an enlisted object that a transaction is being committed.
(Inherited from FileManager.)
Public methodDispose
Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
(Inherited from FileManager.)
Protected methodDispose(Boolean)
Releases unmanaged and - optionally - managed resources.
(Inherited from FileManager.)
Public methodEnlistVolatile
Enlists this instance as a volatile resource manager using the specified enlistment options.
(Inherited from FileManager.)
Public methodEquals
Determines whether the specified object is equal to the current object.
(Inherited from Object.)
Protected methodFinalize
Allows an object to try to free resources and perform other cleanup operations before it is reclaimed by garbage collection.
(Inherited from Object.)
Public methodGetHashCode
Serves as the default hash function.
(Inherited from Object.)
Public methodGetType
Gets the Type of the current instance.
(Inherited from Object.)
Public methodInDoubt
Notifies an enlisted object that the status of a transaction is in doubt.
(Inherited from FileManager.)
Protected methodMemberwiseClone
Creates a shallow copy of the current Object.
(Inherited from Object.)
Protected methodOnCommit
Called when the transaction is successfully committed.
(Inherited from FileManager.)
Protected methodOnInDoubt
Called when the transaction is in doubt.
(Inherited from FileManager.)
Protected methodOnPrepareFileStream
Prepares the stream for managing the file.
(Overrides FileManagerOnPrepareFileStream(String).)
Protected methodOnRollback
Called when the transaction is rolled back.
(Overrides FileManagerOnRollback.)
Public methodPrepare
Notifies an enlisted object that a transaction is being prepared for commitment.
(Inherited from FileManager.)
Public methodRollback
Notifies an enlisted object that a transaction is being rolled back (aborted).
(Inherited from FileManager.)
Public methodToString
Returns a string that represents the current object.
(Inherited from Object.)
Top
Remarks

When an EditFileManager instance is notified that a transaction is being prepared for commitment, it checks if a file having the specified path already exists. If not, the operation cannot be executed and the transaction is forced to roll back.

Notes to Inheritors

A class derived from EditFileManager must implement method OnCommit to state how the managed file should be edited.

Examples

In the following example, a file manager edits a document in XML format in case of a successfully committed transaction.

C#
using System;
using System.IO;
using System.Linq;
using System.Text;
using System.Transactions;
using System.Xml;
using System.Xml.Linq;

namespace Novacta.Transactions.IO.CodeExamples
{
    /// <summary>
    /// Edits a file containing an XML document.
    /// </summary>
    public class EditXmlFileManager : EditFileManager
    {
        /// <summary>
        /// Initializes a new instance of the 
        /// <see cref="EditXmlFileManager"/> class.
        /// </summary>
        /// <param name="path">The path of the managed file.</param>
        public EditXmlFileManager(
            string path) : base(path)
        {
        }

        /// <summary>
        /// Called when the transaction is successfully committed.
        /// </summary>
        /// <remarks>
        /// <para>
        /// This method looks for an <c>items</c> node and, 
        /// if found, add a child <c>item</c> node having 
        /// <c>0002</c> as its <c>id</c> and 
        /// <c>A new item</c> as its <c>description</c>. 
        /// </para>
        /// </remarks>
        protected override void OnCommit()
        {
            var document = XDocument.Load(this.ManagedFileStream);

            var items = from node in document.Descendants()
                        where node.Name == "items"
                        select node;

            var itemsNode = items.FirstOrDefault();

            if (itemsNode != null)
            {
                XElement newItem = new XElement("item",
                    new XElement("id", "0002"),
                    new XElement("description", "A new item"));
                itemsNode.Add(newItem);
            }

            // Truncate the stream to delete the old content.
            this.ManagedFileStream.SetLength(0);

            var xmlTextWriter = new XmlTextWriter(this.ManagedFileStream, Encoding.UTF8);
            xmlTextWriter.Formatting = Formatting.Indented;
            document.Save(this.ManagedFileStream);
        }
    }

    public class EditFileManagerExample0  
    {
        public void Main()
        {
            // Define the XML document to be edited in case 
            // of a successfully committed transaction.
            var document = new XDocument();
            string content =
                "<?xml version='1.0' encoding='utf-8'?>" +
                "<items>" +
                    "<item>" +
                    "<id>0001</id>" +
                    "<description>A mysterious item</description>" +
                    "</item>" +
                "</items>";
            document = XDocument.Parse(content);

            // Define the path for the file where 
            // the document is saved.
            var managedPath = "edit-file-0.xml";

            // Save the document in a file. 
            // This will be edited in case of a 
            // successfully committed transaction.
            using (FileStream stream =
                new FileStream(managedPath, FileMode.Create))
            {
                document.Save(stream, SaveOptions.None);
            }

            // Create the manager.
            var manager = new EditXmlFileManager(managedPath);

            bool transactionSuccessfullyCommitted = true;

            try
            {
                // Create a TransactionScope to manage 
                // your resources, such as files or database
                // connections. In this way, it is guaranteed 
                // that the managing actions can commit or roll back 
                // as a single unit of work.
                using (TransactionScope scope = new TransactionScope())
                {
                    // Enlist the manager.
                    manager.EnlistVolatile(EnlistmentOptions.None);

                    // Add here additional resource managers,
                    // such as database connections, that need
                    // enlisting in the current transaction.

                    // The Complete method commits the transaction. 
                    // If an exception has been thrown, Complete 
                    // is not called and the transaction is rolled back.
                    scope.Complete();
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("Transaction aborted.");
                Console.WriteLine("Reason:");
                Console.WriteLine(e);
                transactionSuccessfullyCommitted = false;
            }
            finally
            {
                if (transactionSuccessfullyCommitted)
                {
                    Console.WriteLine("Transaction successfully committed.");
                }
            }
            bool fileExists = File.Exists(managedPath);
            Console.WriteLine("File exists? {0}.", fileExists);
            if (fileExists)
            {
                // We want to access the managed file to inspect its 
                // edited content, hence we need to dispose 
                // its manager.
                manager.Dispose();

                using (Stream stream = File.OpenRead(managedPath))
                {
                    XDocument savedDocument = XDocument.Load(stream);

                    Console.WriteLine("File content:");
                    Console.WriteLine(savedDocument);
                }
            }
        }
    }
}

// Executing method Main() produces the following output:
// 
// Transaction successfully committed.
// File exists? True.
// File content:
// <items>
//   <item>
//     <id>0001</id>
//     <description>A mysterious item</description>
//   </item>
//   <item>
//     <id>0002</id>
//     <description>A new item</description>
//   </item>
// </items>

See Also