![]() | Creating non-empty files |
By default, a CreateFileManager instance creates an empty file. To add content to a created file, a class derived from CreateFileManager must override method OnCommit.
In the following example, a file manager creates a document in XML format in case of a successfully committed transaction.
using System; using System.IO; using System.Text; using System.Transactions; using System.Xml; using System.Xml.Linq; namespace Novacta.Transactions.IO.CodeExamples { /// <summary> /// Creates a file from an XML document. /// </summary> public class CreateXmlFileManager : CreateFileManager { XDocument xmlDocument; /// <summary> /// Initializes a new instance of the <see cref="CreateXmlFileManager"/> class. /// </summary> /// <param name="path">The path of the managed file.</param> /// <param name="xmlDocument">The XML document to save in the /// managed file.</param> public CreateXmlFileManager( string path, XDocument xmlDocument) : base(path, overwrite: true) { this.xmlDocument = xmlDocument ?? throw new ArgumentNullException(nameof(xmlDocument)); } /// <summary> /// Called when the transaction is successfully committed. /// </summary> protected override void OnCommit() { var xmlTextWriter = new XmlTextWriter(this.ManagedFileStream, Encoding.UTF8); xmlTextWriter.Formatting = Formatting.Indented; this.xmlDocument.Save(this.ManagedFileStream); } } public class CreateFileManagerExample0 { public void Main() { // Define the XML document to be saved 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 to be managed. var managedPath = "create-file-0.xml"; // Create the manager. var manager = new CreateXmlFileManager( managedPath, document); 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 // 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> // </items>