I ran into the "problem" that I'm quite often now reusing/copy'n'pasting code that checks if a nHibernate ISession is currently in a transaction and if not starts one.
Now I thought it would be nice if I just made a static method in a utility class that I can provide with an ISession object and a delegate that contains the actual database code and then use just that method to encapsulate that stuff in a transaction if there wasn't one ongoing just yet.
So here's what I came up with.
public static class TransactionUtils
{
public static void EncloseInTransaction(ISession session, Action<ISession> codeToEnclose)
{
if (session == null)
throw new ArgumentNullException("session");
var isInTrans = session.Transaction != null && session.Transaction.IsActive;
var tx = isInTrans ? session.Transaction : session.BeginTransaction();
try
{
codeToEnclose(session);
if (!isInTrans)
tx.Commit();
}
catch (Exception e)
{
tx.Rollback();
throw;
}
finally
{
if (!isInTrans)
tx.Dispose();
}
}
}
So this is all nice and well I guess. But using that code looks something like this.
TransactionUtils.EncloseInTransaction(session, session1 =>
{
session1.Query<Blahblah>().Where(x.Blub == "meh").ToList();
session1.CreateQuery("update Foo set Urgs=:Moo where Id=:Id")
.SetParameter("moo", "baaahh")
.SetParameter("Id", 12305)
.ExecuteUpdate();
} );
I don't really like the (session, session1 =>...) part here. Looks confusing as hell and someone could just use session instead of session1 inside the code passed to the delegate.
So basically my question is. Would it actually be a problem if I ditched the Action<ISession> and replaced it with only Action and then just used session inside the code? I know there's much magic happening there but as i understand it if i reference session inside the delegates code the compiler provides a pointer to the session object inside there. Or something or other. And i could basically just use that.
You can make that method an extension method, that should make the code look much nicer.
public static void EncloseInTransaction(this ISession session, Action<ISession> codeToEnclose)
And calling the method:
session.EncloseInTransaction(s =>
{
s.Query<Blahblah>().Where(x.Blub == "meh").ToList();
s.CreateQuery("update Foo set Urgs=:Moo where Id=:Id")
.SetParameter("moo", "baaahh")
.SetParameter("Id", 12305)
.ExecuteUpdate();
});
You can also use Action like you said (which is ok) and it would look like this:
public static void EncloseInTransaction(this ISession session, Action codeToEnclose)
Calling the method:
session.EncloseInTransaction(() =>
{
session.Query<Blahblah>().Where(x.Blub == "meh").ToList();
session.CreateQuery("update Foo set Urgs=:Moo where Id=:Id")
.SetParameter("moo", "baaahh")
.SetParameter("Id", 12305)
.ExecuteUpdate();
});
Related
I want to know whether passed object is actually reference of variable of specific class or not.
Consider below structure of some class 'ClassA':
public classA
{
string variable1;
int variable2;
method1(ref variable1);
}
Now if in class that contains implementation of method1(Obj object1), I want to check that 'object1' is which variable of specific 'ClassA' ?
Because I want to check in if condition like if object1 is variable1 of ClassA then //to proceed with logic....
Please provide a small example for the same.
The closest you could get to this in safe code is using expressions, but honestly you probably don't want to do this. It'd be a nightmare to try and debug, and there's probably another way to go about it. For example, is there any reason variable1 can't be of a specific type?
Now that I've spoken reason, the approach using expressions goes something like this (This is from a debugging helper, I would never use this approach in anything remotely serious. Note: A lot of exception handling and other code is stripped from this, also note how ugly and hackish it looks, that's all why you really shouldn't do this):
public static void DoStuffWithParameter<T>(Expression<Func<T>> paramExpression)
{
if (paramExpression == null) throw new ArgumentNullException("paramExpression");
var body = ((MemberExpression)paramExpression.Body);
var paramName = body.Member.Name;
var param = ((FieldInfo)body.Member)
.GetValue(((ConstantExpression)body.Expression).Value);
var declaringType = param.DeclaringType;
var paramValue = paramExpression
.Compile()
.Invoke();
if(declaringType.Equals(typeof(ClassA)))
{
//do stuff
}
}
To use that you'd use something like:
DoStuffWithParameter(()=>myClass.VarA);
I found solution. The simplest way to do this is to pass object of sender in method1 and proceed, like below.
method1(Object sender, ref Object var)
{
if(sender is classA)
{
classA senderObj= (classA) sender;
if((string)var == senderObj.variable1)
{
// Logic for variable1
}
else if((int)var == senderObj.variable2)
{
// Logic for variable2
}
. . .
}
}
I have a class in my program of which I want only one copy. I don't want to use the Singleton pattern though for a couple of reasons (* see below). I know that I'll only have one copy of the class because I'll be the only one calling its constructor.
In my class's constructor, I want to check that only one copy of the class will exist and throw an exception if more than one exists. Is the code below a good pattern to use for this case?
public class MySingletonAlternative : IDisposable
{
private static int _count = 0;
public MySingletonAlternative()
{
int newValue = System.Threading.Interlocked.Increment(ref _count);
if (newValue > 1)
{
throw new NotImplementedException();
}
}
public void Dispose()
{
int newValue = System.Threading.Interlocked.Decrement(ref _count);
if (newValue < 0)
{
throw new ObjectDisposedException("MySingletonAlternative");
}
}
}
* Why I don't want to use a Singleton:
I want to be able to control when the class is created. In the traditional C# Singleton pattern, construction happens non-deterministically.
I want to avoid global variables.
When I'm debugging my code and an exception is raised in the Singleton's private constructor, Visual Studio highlights the exception, but it highlights the wrong line of code, usually in a different file.
I don't want to create this object lazily (using Lazy<T>). One instance of this class will exist for the life of my application. I gain nothing by constructing it lazily.
Use a IoC Container like an UnityContainer. It will erase all of your points you've mentioned why you don't want to use a Singleton (in the means of global variables or static). You will be able to fully controll the creation of your lifetime-instance and inject it into all classes that will need to use this.
Can you use dependency injection and then have the di container manage the lifetime of the class you want to create? an example is with Unity and the ContainerControlledLifetimeManager
http://msdn.microsoft.com/en-us/library/dn178463(v=pandp.30).aspx#sec34
DON'T USE THIS CODE BELOW IN REAL APPLICATIONS! It's just for demo purposes.
I guess it's not a good way, but it looks like that your approach will work just fine. I am not aware of edge cases though.
Just created a little test app to create 1 million instances in a for loop and count
the exceptions it raises.
In this case it should be: 1 instance successfully created and 999.000 exceptions raised.
I ran the test app a couple of times and it always returned 999.000.
Depending on your machine this code could take some time to finish,
cause it throws 999.000 exceptions.
public static volatile int _global_Exception_count = 0;
static async Task Main(string[] args)
{
_global_Exception_count = 0;
var list = Enumerable.Range(1, 1000000).ToList();
var tlist = list.Select(async item =>
{
MySingletonAlternative current = null;
try
{
current = new MySingletonAlternative();
}
catch (Exception ex) { System.Threading.Interlocked.Increment(ref _global_Exception_count); }
return await Task.FromResult(0);
});
await Task.WhenAll(tlist);
Console.WriteLine(_global_Exception_count);
}// end main
I have created a PhoneBook style application; on my phonebook object I have a local member _site which is used as a filter, since there are approximately 1000 phone numbers, split across 12 sites within my organisation. Only one site will be retrieved at a time using this method.
This was my original method. The GUI has several methods for reordering the data, so I left it as an IQueryable because I would like to defer SQL to allow for filtering to be done on the SQL server rather than on the client PC.
Works
public IQueryable<PhoneNumber> GetPhoneDirectory()
{
PhoneBookDataContext db = new PhoneBookDataContext())
return db.PhoneNumbers.Where(d => d.Site == _site);
}
However, I am also trying to keep to 'best practise' in terms of using statements.
Doesn't Work
public IQueryable<PhoneNumber> GetPhoneDirectory()
{
using (PhoneBookDataContext db = new PhoneBookDataContext())
{
return db.PhoneNumbers.Where(d => d.Site == _site);
}
}
Now as pointed out by #justanotheruseryoumay, this will cause an exception because the datacontext is disposed by the time the objects are accessed.
I guess what I am asking is, how can I make sure my data context is disposed nicely, when I cannot use a 'using' statement and don't strictly know when the context is done with.
If you want to return IQueryable you can make your class that contains the GetPhoneDirectory disposable, make the PhoneBookDataContext a field, and dispose it in your dispose method.
You will then put the onus on the caller to dispose his instance of your class.
E.g.
public class MyClass : IDisposable
{
PhoneBookDataContext db;
public MyClass()
{
db = new PhoneBookDataContext();
}
public IQueryable<PhoneNumber> GetPhoneDirectory()
{
return db.PhoneNumbers.Where(d => d.Site == _site);
}
public void Dispose()
{
if (db != null)
{
db.Dispose();
db = null;
}
}
}
// Caller
using(var myClass = new MyClass())
{
var queryable = myClass.GetPhoneDirectory();
...
}
The execution of the query will still be deferred and the PhoneBookDataContext will still be properly Disposed because using is interpreted by the compile as a try/finally. When you actually execute the query it will result in a runtime error because the PhoneBookDataContext no longer exists. I would suggest doing a .ToList() on your query and returning it that way. If you want to change the order after you return it then you can still do LINQ on it as you please.
EDIT:
Another thing you could do is to create the using with the PhoneBookDataContext in the calling method and pass in the context. The context is really going to be used in that method anyway and you can keep it around as long as you need it and stick with the good using format.
Yes; It is bad design because your IQueryable<PhoneNumber> will be evaluated only when you call a method that cause it to be evaluated, like ToList() or when you iterate it with foreach.
in your code you are returning a IQueryable<PhoneNumber> which is not evaluated yet, and before the caller get any chance to execute it, it's internals that has the responsibility for yielding the records to you (db); is already disposed.
Just as a suggestion:
public IEnumerable<PhoneNumber> GetPhoneDirectory()
{
using (PhoneBookDataContext db = new PhoneBookDataContext())
{
return db.PhoneNumbers.Where(d => d.Site == _site).ToList();
}
}
Or relocate the db object to somewhere else in your design (Unit Of Work and Repository are nice patterns to get a look at IMHO).
I am new to developing in .NET and C#, but have been a long-time developer, working with C, C++, Java, PHP, etc.
I have an MVC3 extension class for my data models that refers to the database. It is set as "private static" in the class, but I think that it is not keeping up with database changes. In other words, when I change data in the controllers, those changes aren't "noticed" in the db because it is static. Currently, I am creating and disposing of the variable for each use, to compensate.
My questions are:
Am I correct that a static db variable could behave that way?
Is it necessary to dispose of the dynamic variable in the static class, or will garbage collection still take care of it automatically?
Here is a relevant snippet of the class:
namespace PBA.Models {
using System;
using System.Text.RegularExpressions;
using PBA.Models;
using PBA.Controllers;
public static class Extensions {
private static PbaDbEntities db = null;
public static PbaDbEntities GetDb() {
// TODO: find out about static memory/disposal, etc.
//
if (db != null) {
db.Dispose();
}
db = new PbaDbEntities();
return db;
}
public static string GetCheckpointState(this Activity activity, long memberProjectId) {
GetDb(); // TODO: Do I need to do this each time, or will a one-time setting work?
string state = CheckpointController.CHECKPOINT_STATUS_NOT_STARTED;
try {
var sub = db.ActivitySubmissions.
Where(s => s.activityId == activity.activityId).
Where(s => s.memberProjectId == memberProjectId).
OrderByDescending(s => s.submitted).
First();
if (sub != null) {
state = sub.checkpointStatusId;
}
}
catch (Exception e) {
// omitted for brevity
}
return state;
}
}
}
Your code will fail horribly in production.
DataContexts are not thread-safe; you must not share a context between requests.
Never put mutable objects in static fields in multi-threaded applications.
Ignoring exceptions that way is a terrible idea, if you don't want to handle exceptions just don't try/catch, or catch & rethrow. Think about it like this, after you've buried the exception, your program is in an invalid state, b/c something you have no control over error'd out. Now, b/c you've buried the exception, your program can continue to operate but it's in a bad state.
If your code makes it to production, 3.5 yrs from now some jr. programmer is going to get involved in some middle of the night firestorm because all of a sudden the website is broken, even though it used to work. It will be completely impossible to track down where the exception is happening so, this poor guy is going to spend 48 straight hours adding logging code all over the place to track down the problem. He will find that some DBA somewhere decided to rename the column MemberProjectId to MemberProjectIdentifier, which caused your linq to blow up.
Think of the children, handle exceptions, don't bury them.
btw - yes, i have been that guy that has to figure out these types of mistakes.
It seems like you need to read about mvc3 and entity framework before writing coding and asking in here for help on something that's coded full of bad practices.
Answering your questions:
1- no
2- makes no sense as the answer to 1
Do it right, here are some useful documentation: http://msdn.microsoft.com/en-us/library/ie/gg416514(v=vs.98).aspx
EDIT: Adding some explicit fix
You could access your dbcontext from an static class, something like this:
var context = DbProvider.CurrentDb;
The idea is to access your db from here always: from your extension methods and from your controller actions.
Then, the implementation of the DbProvider.CurrentDb will be something like this:
public static classDbProvider {
public static void Initialize(){
HttpContext.Current.ApplicationInstance.BeginRequest += CreateDb;
HttpConetxt.Current.ApplicationInstance.EndRequest += DisposeDb;
}
private static void CreateDb(object sender, EventArgs e) {
HttpContext.Items.Add("CurrentDb", new PbaDbEntities(););
}
private static void DisposeDb(object sender, EventArgs e)
{
Current.Dispose();
HttpContext.Items.Remove("CurrentDb");
}
public static PbaDbEntities CurrentDb{
get {
return (PbaDbEntities)HttpContext.Current.Items["CurrentDb"];
}
}
}
As you can see, it will create a new Db per each request and it will be available ONLY in that request. In that way, your db will be disposed at the end of each request. This pattern is called Open-Session-in-View.
Finally, you need to initialize the DbProvider calling the method
Initialize() in your Global.asax file, in the event Application_start.
Hope it helps.
I don't have any idea of the context here-- if db is simply a connection-like object or not, but it appears you are throwing away and recreating whatever it is unnecessarily.
Best to create a property (for whatever your doing) so to be consistent.
private static Thing _thing;
private static Thing thing{
get{
if(_thing==null){
_thing=new Thing();
}
return _thing;
}
}
I've been spending about an hour searching for a concensus on something I'm trying to accomplish, but have yet to find anything conclusive in a particular direction.
My situation is as follows:
I have a multi-threaded application (.NET web service)
I have classes that use objects that take non-negligible time to load, so I would like to maintain them as static class members
The code that constructs these objects intermittently has a low chance of failure
I was previously using an approach that constructs these objects in a static constructor. The problem with this was that, as mentioned above, the constructor would occasionally fail, and once a .NET static constructor fails, the whole class is hosed until the process is restarted. There are no second chances with that approach.
The most intuitive-seeming approach after this was to use double-checked locking. There are a lot of pages around that talk about the evils of double-checked locking and say to use a static constructor, which I was already doing, but that doesn't seem to be an option for me, as the static constructor has the potential to fail and bring down the whole class.
The implementation (simplified, of course) I'm thinking of using is the following. All class and member names are purely demonstrative and not what I'm actually using. Is this approach going to be problematic? Can anyone suggest a better approach?
public class LazyMembers
{
private static volatile XmlDocument s_doc;
private static volatile XmlNamespaceManager s_nsmgr;
private static readonly object s_lock = new object();
private static void EnsureStaticMembers()
{
if (s_doc == null || s_nsmgr == null)
{
lock (s_lock)
{
if (s_doc == null || s_nsmgr == null)
{
// The following method might fail
// with an exception, but if it succeeds,
// s_doc and s_nsmgr will be initialized
s_doc = LoadDoc(out s_nsmgr);
}
}
}
}
public XmlNamespaceManager NamespaceManager
{
get
{
EnsureStaticMembers();
return s_nsmgr;
}
}
public XmlDocument GetDocClone()
{
EnsureStaticMembers();
return (XmlDocument)s_doc.Clone();
}
}
If you use .NET 4.0 you can refer to Lazy<T> and LazyThreadSafetyMode (it depends on whether you want few instances of T to be created or not in multithreaded environment. In your case you need to refer to Lazy<T>(Func<T> func, LazyThreadSafetyMode) constructor - here(MSDN)
Otherwise (if you use 3.5 or lower) you can CAS techinque to create single instance without locking.
Something like this:
get {
if( _instance == null) {
var singleton = new Singleton();
if(Interlocked.CompareExchange(ref _instance, singleton, null) != null) {
if (singleton is IDisposable) singleton.Dispose();
}
}
return _instance;
}
However, here you can only achieve LazyThreadSafetyMode.Publications behaviour - only one instance will be visible to other threads but few can be created.
Also, there should not be any problems with double check for null in your code - it's safe in .NET world (at least on x86 machines and associated memory model). There were some problems in Java world before 2004, AFAIK.