Hi!
I am just starting to work with .NET and I was very surprised when I learned that there is nothing similar to EJB, which is natively implemented in the .NET FrameWork. So I was very happy to discover NHibernate but I am not accustomed to use Hibernate, that's why I try to retrieve something nearer to EJB and I need opinions about this implementation.
I do not want that the user cares about the session, like the EntityManager in EJB, that's why I use a singleton pattern to obtain it and I keep it alive in order to use lazy loading. Is it possible to keep this session alive during all the application ?
Code:
internal class SessionFactory {
private static SessionFactory apoSession = null;
private static ISession session;
private static ISessionFactory factory;
private SessionFactory(string assembly) {
Configuration config = new Configuration();
config.AddAssembly(Assembly.LoadFrom(assembly));
factory = config.BuildSessionFactory();
session = factory.OpenSession();
}
internal static ISession CreateSessionWith(String assembly) {
if (apoSession == null)
apoSession = new SessionFactory(assembly);
return session;
}
internal static void CloseSession() {
session.Flush();
session.Dispose();
factory.Close();
}
}
After this, I try to develop somethink like an EJB Session which could be generic to all the entities.
Code:
public class EntitiesManager<T> {
private static ISession m_Session;
public EntitiesManager(string assembly) {
m_Session = SessionFactory.CreateSessionWith(assembly);
}
/*public static ISession Session {
get { return m_Session; }
}*/
public void SaveOrUpdate(object o) {
ITransaction tx = null;
try {
tx = m_Session.BeginTransaction();
m_Session.SaveOrUpdate(o);
tx.Commit();
} catch (Exception ex) {
Console.Write(ex);
tx.Rollback();
}
}
public T Get(int id) {
T t = default(T);
ITransaction tx = null;
try {
tx = m_Session.BeginTransaction();
t = (T)m_Session.Get(typeof(T), id);
tx.Commit();
} catch (Exception ex) {
Console.Write(ex);
tx.Rollback();
}
return t;
}
public void Delete(object o) {
ITransaction tx = null;
try {
tx = m_Session.BeginTransaction();
m_Session.Delete(o);
tx.Commit();
} catch (Exception ex) {
Console.Write(ex);
tx.Rollback();
}
}
}
Finally after implementing the entities classes and the mapping files I can use it like this:
Code:
EntitiesManager<Client> cm = new EntitiesManager<Client>(assembly);
EntitiesManager<Product> pm = new EntitiesManager<Product>(assembly);
/*=====Write a Client=====*/
Client c1 = new Client();
c1.FirstName = "Dupond";
c1.LastName = "Roger";
cm.SaveOrUpdate(c1);
/*=====Read the Client=====*/
Client c10 = cm.Get(1);
Console.WriteLine("Client\t Id: {0}\t FirstName: {1}\t LastName: {2}", c10.Id, c10.FirstName, c10.LastName);
/*=====Write a Product=====*/
Product p1 = new Product();
p1.Name = "Mir vaisselle";
p1.Price = 1.09f;
pm.SaveOrUpdate(p1);
/*=====Read the Product=====*/
Product p10 = pm.Get(1);
Console.WriteLine("Product\t Id: {0}\t PType: {1}\t Name: {2}\t Price: {3}", p10.Id, p10.ProductType.Name, p10.Name, p10.Price);
My real problem is that contrary to EJB, I must initialize the EntitiesManager (of course i can't use @EJB EntitiesManager<...> em) and so I don't know how to implement an automaticaly destruction and closing of the Session and the EntitiesManager.
If I add a Close() in the generic EntitiesManager which call SessionFactory.CloseSession(), the user will use it many times to close all his EntitiesManagers (<Client>, <Product>...) which will throws Exception.
I think about building a counter in the SessionFactory which will know the number of EntitiesManager, incremented when I make a new EntitiesManager and when it reach zero, by calling their Close(), SessionFactory.CloseOperation will be called.
Is it a good implementation, a anti pattern ? Will I encounter problems of optimization ? Does it already exist something similar which is already implemented ? I read a lot about NHibernate but I didn't found something similar...
Thx a lot!