Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom "using" blocks

Tags:

c#

I am working with a database, and there is a situation where I want to turn off a feature in it. Turning off the feature looks something like this...

DatabaseContext.Advanced.UseOptimisticConcurrency = false;

Turning it on is just as easy. This functions fine. But I was curious about something and wanted to explore it ...

Is it possible to wrap this in a "using" block like we do with things like dispose and unsafe? For instance...

using(DatabaseContext.Advanced.UseOptimisticConcurrency = false){
   // do things!
}

// the feature is turned back on automatically here!

Update

With the help of the great people here at StackOverflow, I have now made the behavior I wanted work perfectly. Thanks again. Here is my working code. Don't mind the verbose documentation. I am just the kind of programmer that types everything in my head out.

using System;

namespace Raven.Client {
    /// <summary>
    /// Used to emulate a series of transactions without optimistic concurrency in RavenDB
    /// </summary>
    /// <remarks>
    /// This has been flagged as an 'abuse' of the IDisposable interface, which is something I will learn more about
    /// and try to find a better solution. The purpose of this class is to make absolutely sure that we never use
    /// a document session without optimistic concurrency unless we are completely certain it is what we want. I
    /// elected to wrap this in a disposable block because that is an easy convention to remember, and it makes the
    /// intention very clear to the others who may see this code.
    /// Topics[0]: http://stackoverflow.com/questions/19643266/custom-using-blocks
    /// Topics[1]: http://stackoverflow.com/questions/2101524/is-it-abusive-to-use-idisposable-and-using-as-a-means-for-getting-scoped-beha/2103158#2103158
    /// Topics[2]: http://stackoverflow.com/questions/538060/proper-use-of-the-idisposable-interface
    /// </remarks>
    public class RavenPessimistic : IDisposable {
        private readonly IDocumentSession RavenSession;

        /// <summary>
        /// Disable optimistic concurrency for this exact session only.
        /// </summary>
        /// <param name="session"></param>
        public RavenPessimistic(IDocumentSession session) {
            RavenSession = session;
            RavenSession.Advanced.UseOptimisticConcurrency = false;
        }

        /// <summary>
        /// Enable the optimistic concurrency again, so that we do not
        /// ever use it unintentionally
        /// </summary>
        public void Dispose() {
            RavenSession.Advanced.UseOptimisticConcurrency = true;
        }
    }

    /// <summary>
    /// An extension method to make it more convenient to get to this. This is probably not necessary, but I have been
    /// anxious to see how RavenDB handles extension methods.
    /// </summary>
    public static class RavenSessionExtensions {
        public static RavenPessimistic OpenPessimisticSession(this IDocumentSession documentSession) {
            return new RavenPessimistic(documentSession);
        }
    }
}

Then, in my actual code...

    /// <summary>
    /// Edit the given item prototype.
    /// </summary>
    /// <param name="model">
    /// A unique prototype to edit in the database.
    /// </param>
    /// <returns></returns>
    [HttpPost]
    [Route("items/edit/prototype")]
    public JsonResult Prototype(Models.Items.Prototype model) {
        if (ModelState.IsValid) {
            // go through the prototype and make sure to set all of the
            // mutation names to it.
            foreach (var mutation in model.Mutations) {
                mutation.Name = model.Name;
            }

            // we are updating an entry, instead of creating a new one,
            // so temporarily turn off optimistic concurrency since we
            // are 100% sure we want to overwrite the existing document.
            using (RavenSession.OpenPessimisticSession()) {
                RavenSession.Store(model);
                RavenSession.SaveChanges();
            }

            // if this was successful, then return the result to the client
            return Json(true, JsonRequestBehavior.AllowGet);
        }

        return Json(false, JsonRequestBehavior.AllowGet);
    }
like image 907
Ciel Avatar asked Oct 28 '13 19:10

Ciel


People also ask

What is a custom block?

Custom blocks are pieces of content that are created independently of a page. Think of them as building block components, or elements, that enhance the pages of a website. Once created, custom blocks will reside in the Custom Block Library. A single custom block can be placed on multiple pages.

What is a custom block in snap?

Custom Blocks are blocks which are not primitive but are rather made by using primitive or other custom blocks. The ability of making custom blocks is one of the main features of Snap! and was the main feature of BYOB (BYOB stands for Build Your Own Blocks).


1 Answers

Just wrap that in a class that is IDisposable and you can revert the functionality in Dispose function.

public class SomeClass : IDisposable
{
     public SomeClass()
     {
          DatabaseContext.Advanced.UseOptimisticConcurrency = false;
     }

     public void Dispose()
     {
         DatabaseContext.Advanced.UseOptimisticConcurrency = true;
     }
}

Above code is just example you need to tweak it according to your needs.

like image 84
Mayank Avatar answered Oct 11 '22 16:10

Mayank