Our DAL has a reference to CSLA, just to leverage the ObjectContextManager. I realize that this class is used to manage the connections to EF from a CSLA application. I would like to eliminate this dependence on the ObjectContextManager, and either write my own, or just use the context for my EF entities.
Just wondering what kind of trouble I would be getting into if I did this.
The main purpose is to have some "reuse" of the same ObjectContextManager and not have to send that instance as a parameter to all objects/methods involved in fetch/update. if you get more than on manager (and connection) the DTC steps into play on updates.
The class in Csla.Data should be fairly easy to "extract" and include in your project.
The problem with extracting it is that it uses ApplicationContext, IMobileObject and SerializationInfo. So not sure how simple it is going to be.
From what I can see the ObjectContextManager only relies on ApplicationContext to provide a named thread slot (LocalContext) to store the ObjectContextManager instance for a given key.
Your data access assembly could create it's own thread slot (context) to store the instance for reference counting or use a dictionary or just use the new MemoryCache in .NET 4.
Thanks for the response Jonny! Do you know of any examples where someone has written a CustomObjectManager or extracted it?
Some more background ... we are using a RESTful service which works with our CSLA library and passes back JSON/XML to the user. So just trying to wrap my mind around how long a database connection lives in the context of a web service call. Does it exist for the life of the web service or just the call? We are really looking for the connection to just exist for the life of the call ... and again, eliminate the reference for CSLA in our DAL factory.
The ObjectContextManager lifecycle should be the same as the WCF/rest call.
Csla serverside DataPortal will make sure to clear the context when result is sent to client (when using the DataPortal).
Do you use the DAL library in both Csla Serverside dataportal AND the WCF Rest service?
If yes - then I'd prefer to keep the CSLA bits and add code to WCF RestService to clear the application context.
Hey Jonny ... where in the book can I read about the lifecycle? Just want to have a clearer understanding.
Not sure of where it is in the book - probably the 2008 book.
But the code to inspect is Csla.Server.DataPortal.cs, take f.ex the Create method:
public DataPortalResult Create(
Type objectType, object criteria, DataPortalContext context)
{
try
{
SetContext(context);
AuthorizeRequest(new AuthorizeRequest(objectType, criteria, DataPortalOperations.Create));
DataPortalResult result;
DataPortalMethodInfo method = DataPortalMethodCache.GetCreateMethod(objectType, criteria);
IDataPortalServer portal;
switch (method.TransactionalType)
{
#if !MONO
case TransactionalTypes.EnterpriseServices:
portal = new ServicedDataPortal();
try
{
result = portal.Create(objectType, criteria, context);
}
finally
{
((ServicedDataPortal)portal).Dispose();
}
break;
#endif
case TransactionalTypes.TransactionScope:
portal = new TransactionalDataPortal();
result = portal.Create(objectType, criteria, context);
break;
default:
portal = new DataPortalSelector();
result = portal.Create(objectType, criteria, context);
break;
}
return result;
}
catch (Csla.Server.DataPortalException ex)
{
Exception tmp = ex;
throw;
}
catch (Exception ex)
{
throw new DataPortalException(
"DataPortal.Create " + Resources.FailedOnServer,
new DataPortalExceptionHandler().InspectException(objectType, criteria, "DataPortal.Create", ex),
new DataPortalResult());
}
finally
{
ClearContext(context);
}
}
The WCF version would probably be to implement your own OperationInvoker and plug into the WCF pipeline or an ICallContextInitializer.
K ... so pulling that out looks like it is going to take some work, to be honest, a bit over my head ... what would I really lose if I just used ctx = new MyEntities(MyConnectionString)?
I was also thinking, if I wrote my own ContextManager that just contained a static reference to the connection, like CSLA. My only concern there, is if that static variable would remain alive across service calls between users ... I wouldn't want this behavior.
Let me know what you think ... and as always, appreciate your insight Jonny!
Hi Matt,
It's not that hard to code or complex as it may seem especially if you do not use async WCF n the Server.
When running on a server - you do not want to us a static reference in a context manager.
CSLA uses a slot in the "CurrentThread" to handle these ContextManagers - and you could also do the same in you code provided that you can have a ContextManager that clears the slot when the call is finished.
See attached Zip file - contains a complete sample with a SimpleCallContextInitializer that clears the ApplicationContext and uses a ObjectContextManager from CSLA. There is no referere to CSLA assemblies.
The "quirky" part is how to configure this into WCF with making any change to the actual WCF Code.
Take a close look at the web.config file and the configuration of behaviorExtensions and endpointBehaviors
It's in the zip file in my previous post. Usage is the same as in CSLA samples.
Copyright (c) Marimer LLC