none
Is it possible to instantiate a ServerApplicationContext inside an attached RIA Service?

    Question

  • I attached a RIA service to a plain V3 LightSwitch solution and added some binary references: Microsoft.LightSwitch.dll and Microsoft.LightSwitch.server.dll.


    By doing so I can (at least in code) setup a ServerApplicationContext inside the RIA domain service

                IServerApplicationContext ctx = null;
                try
                {
                    ctx = ServerApplicationContextFactory.CreateContext();
    
                }
                catch (Exception e)
                {
    
                    var z = e.Message;
                }

    But, unfortunately this gives error:

    "A server application context cannot be created when one already exists in scope.  Dispose of the other context before creating a new one."

    Any idea how to proceed ?


    paul van bladel

    Wednesday, April 24, 2013 6:15 PM

Answers

  • If it's already existing can't you simply apply the using approach?


    Johnny Larue, http://www.softlandingcanada.com

    Wednesday, April 24, 2013 7:52 PM
  • For future reference, since this is the only sensible page returned by Google/Bing on the issue (and of course it is Paul who started it hehe ;))...

    I ran into the same issue.  Apparently when you use the ServerApplicationContext like all the MSDN examples state:

                            using (ServerApplicationContext ctx = ServerApplicationContext.CreateContext())
                            {
                            }


    You can run into problems because a ServerApplicationContext can only be opened once at a time.  So this code throws the "context already exists in scope" error mentioned above:

                            using (ServerApplicationContext ctx = ServerApplicationContext.CreateContext())
                            {
                                using (ServerApplicationContext secondCtx = ServerApplicationContext.CreateContext())
                                {
                                }
                            }

    As is, the code might seem a bit silly, but when you have a larger OO system then a particular class might open a context and do some stuff, and that stuff in return opens a context to...

    boom.

    I would suggest Michael's pattern except for the fact that it doesn't clean up resources well.  Hence I modified it to this helper class:

        public static class ServerApplicationContextProvider
        {
            public static IDisposable GetCurrentOrNewApplicationContext(out ServerApplicationContext applicationContext) {
                applicationContext = ServerApplicationContext.Current;
                if (applicationContext != null)
                {
                    return new NoopDisposer();
                }
                else
                {
                    applicationContext = ServerApplicationContext.CreateContext();
                    return applicationContext;
                } 
            }
    
    
            private class NoopDisposer : IDisposable
            { 
                public void Dispose()
                { 
                }
            } 
              
        }

    To use it, change every line that says:

                            using (ServerApplicationContext ctx = ServerApplicationContext.CreateContext())
                            {
                            }

    To:

                            ServerApplicationContext ctx; 
                            using (ServerApplicationContextProvider.GetCurrentOrNewApplicationContext(out ctx))  
                            {

    That way, you' always have the "right" application context (Current OR new) and it will be disposed of properly.

    Keep rocking LS!

    Jan 

    PS: Any LS experts that could verify the correctness / that there are no side effects to my code, will be appreciated!


    It's your story - time to switch on the innovation.||About me||LightSwitch blog

    Thursday, November 07, 2013 3:55 PM

All replies

  • If it's already existing can't you simply apply the using approach?


    Johnny Larue, http://www.softlandingcanada.com

    Wednesday, April 24, 2013 7:52 PM
  • of course !

    Many thanks Johnny.


    paul van bladel

    Wednesday, April 24, 2013 8:02 PM
  • This pattern works for me:

            private static ServerApplicationContext GetServerContext()
            {
                ServerApplicationContext serverContext = 
                    (LightSwitchApplication.ServerApplicationContext)ServerApplicationContext.Current;
                if (serverContext == null)
                {
                    serverContext = 
                        (LightSwitchApplication.ServerApplicationContext)ServerApplicationContext.CreateContext();
                }
                return serverContext;
            } 
    


    The Visual Studio LightSwitch Marketplace

    http://LightSwitchHelpWebsite.com

    Wednesday, April 24, 2013 8:59 PM
  • yeah indeed, that's also the way I'm normally doing it... 

    but I was wrongly assuming that in the case of a RIA service there would be not context yet, but of course it is, because it's the LS server who hands over control to the attached RIA dll.

    I'm trying now to speak inside the context also to the MEF container of the LS server dll, but that's apparently a bridge too far :)


    paul van bladel

    Thursday, April 25, 2013 12:50 PM
  • For future reference, since this is the only sensible page returned by Google/Bing on the issue (and of course it is Paul who started it hehe ;))...

    I ran into the same issue.  Apparently when you use the ServerApplicationContext like all the MSDN examples state:

                            using (ServerApplicationContext ctx = ServerApplicationContext.CreateContext())
                            {
                            }


    You can run into problems because a ServerApplicationContext can only be opened once at a time.  So this code throws the "context already exists in scope" error mentioned above:

                            using (ServerApplicationContext ctx = ServerApplicationContext.CreateContext())
                            {
                                using (ServerApplicationContext secondCtx = ServerApplicationContext.CreateContext())
                                {
                                }
                            }

    As is, the code might seem a bit silly, but when you have a larger OO system then a particular class might open a context and do some stuff, and that stuff in return opens a context to...

    boom.

    I would suggest Michael's pattern except for the fact that it doesn't clean up resources well.  Hence I modified it to this helper class:

        public static class ServerApplicationContextProvider
        {
            public static IDisposable GetCurrentOrNewApplicationContext(out ServerApplicationContext applicationContext) {
                applicationContext = ServerApplicationContext.Current;
                if (applicationContext != null)
                {
                    return new NoopDisposer();
                }
                else
                {
                    applicationContext = ServerApplicationContext.CreateContext();
                    return applicationContext;
                } 
            }
    
    
            private class NoopDisposer : IDisposable
            { 
                public void Dispose()
                { 
                }
            } 
              
        }

    To use it, change every line that says:

                            using (ServerApplicationContext ctx = ServerApplicationContext.CreateContext())
                            {
                            }

    To:

                            ServerApplicationContext ctx; 
                            using (ServerApplicationContextProvider.GetCurrentOrNewApplicationContext(out ctx))  
                            {

    That way, you' always have the "right" application context (Current OR new) and it will be disposed of properly.

    Keep rocking LS!

    Jan 

    PS: Any LS experts that could verify the correctness / that there are no side effects to my code, will be appreciated!


    It's your story - time to switch on the innovation.||About me||LightSwitch blog

    Thursday, November 07, 2013 3:55 PM
  • Jan,

    Brilliant, man !

    Can I ask you a favor? Could you explain the "NoopDisposer"?

    Cheers.


    paul van bladel

    Saturday, November 09, 2013 9:47 AM
  • Hey Buddy,

    here's my 2 cents: 

    In the code uses a disposable resource, you should always wrap it in a using block to make sure it gets cleaned up nicely.

      ServerApplicationContext ctx; 
                            using (ServerApplicationContextProvider.GetCurrentOrNewApplicationContext(out ctx))  
                            {


    The question here is: should the ServerApplicationContext ctx really be disposed at the end of this using block?  

    If it was a brand new ServerApplicationContext created right here, then yes, it should be properly disposed.  However, if there already was an active ServerApplicationContext, disposing it at the end of this using block is not desirable.  If a higher level class already opened a ServerApplicationContext before the code hit this block, it's his responsibility to clean it up, not ours.  

    Hence, in the case there was no active ServerApplicationContext, the ServerApplicationContextProvider returns the freshly created ServerApplicationContext as the IDisposable.

    If there was already an active ServerApplicationCOntext, the ServerApplicationContextProvider returns a dummy that does no operations at all when disposed of.

    Hope that makes some sense.  

    Take care and keep rocking LS!

    Jan


    It's your story - time to switch on the innovation.||About me||LightSwitch blog

    Saturday, November 09, 2013 4:05 PM
  • Thanks Jan. 

    Make sense, ... a lot.

    Cheers.


    paul van bladel

    Monday, November 11, 2013 7:12 AM