Last active 1 month ago

Playing with Services Producer for NHibernate in C#

racerxdl's Avatar Lucas Teske revised this gist 9 years ago. Go to revision

3 files changed, 34 insertions, 30 deletions

BaseService.cs

@@ -1,16 +1,10 @@
1 - using NHibernate;
2 - using System;
3 - using System.Collections.Generic;
4 - using System.Linq;
5 - using System.Text;
6 - using System.Threading.Tasks;
1 + using NHibernate;
7 2
8 3 namespace DatabaseSample {
9 4 public class BaseService {
10 - public static ISessionFactory _sessionFactory;
11 - protected static ISession _session = null;
5 + protected ISession _session = null;
12 6
13 - protected static ISession Session {
7 + protected ISession Session {
14 8 get { return _session; }
15 9 }
16 10 }

EmployeeService.cs

@@ -1,4 +1,4 @@
1 - using DatabaseSample.Models;
1 + using DatabaseSample.Models;
2 2 using System;
3 3 using System.Collections.Generic;
4 4 using System.Linq;
@@ -28,4 +28,4 @@ namespace DatabaseSample {
28 28 }
29 29 }
30 30 }
31 - }
31 + }

ServiceProducer.cs

@@ -1,28 +1,31 @@
1 1 using NHibernate;
2 2 using System;
3 - using System.Collections.Generic;
4 3 using System.Linq;
5 4 using System.Reflection;
6 5 using System.Reflection.Emit;
7 - using System.Text;
8 - using System.Threading.Tasks;
9 6
10 7 namespace DatabaseSample {
11 - public static class ServiceProducer<T> {
8 + public static class ServiceProducer<T> where T: BaseService {
12 9
13 - public static T ProduceService() {
14 - var myType = CompileResultType<T>();
15 - return (T)Activator.CreateInstance(myType);
10 + private static readonly string generatedSessionFactoryFieldName = "__generated_session_factory";
11 + private static readonly string generatedTypePrefix = "__customType_";
12 +
13 + public static T ProduceService(ISessionFactory sessionFactory) {
14 + var myType = CompileResultType();
15 + T data = (T)Activator.CreateInstance(myType);
16 + myType.GetField(generatedSessionFactoryFieldName, BindingFlags.Instance | BindingFlags.NonPublic).SetValue(data, sessionFactory);
17 + return data;
16 18 }
17 19
18 - public static Type CompileResultType<T>() {
19 - TypeBuilder tb = GetTypeBuilder<T>();
20 + private static Type CompileResultType() {
21 + TypeBuilder tb = GetTypeBuilder();
20 22 ConstructorBuilder constructor = tb.DefineDefaultConstructor(MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName);
21 23
22 24 return tb.CreateType();
23 25 }
24 - private static TypeBuilder GetTypeBuilder<T>() {
25 - var typeSignature = "customType_" + typeof(T).Name;
26 +
27 + private static TypeBuilder GetTypeBuilder() {
28 + var typeSignature = generatedTypePrefix + typeof(T).Name;
26 29 var an = new AssemblyName(typeSignature);
27 30 AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(an, AssemblyBuilderAccess.Run);
28 31 ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("MainModule");
@@ -35,6 +38,8 @@ namespace DatabaseSample {
35 38 TypeAttributes.AutoLayout
36 39 , typeof(T));
37 40
41 + FieldBuilder fieldBuilder = tb.DefineField(generatedSessionFactoryFieldName, typeof(ISessionFactory), FieldAttributes.Private);
42 +
38 43 typeof(T).GetMethods().ToList().ForEach(m => {
39 44 MethodBuilder mbM = tb.DefineMethod(m.Name, MethodAttributes.Public | MethodAttributes.ReuseSlot | MethodAttributes.Virtual | MethodAttributes.HideBySig,
40 45 m.ReturnType,
@@ -56,10 +61,11 @@ namespace DatabaseSample {
56 61 // try {
57 62 il.BeginExceptionBlock();
58 63
59 - // BaseService._session = BaseService._sessionFactory.OpenSession();
64 + // _session = _sessionFactory.OpenSession();
60 65 writeLine(il, "GettingSession");
61 66 il.Emit(OpCodes.Nop);
62 - il.Emit(OpCodes.Ldsfld, typeof(BaseService).GetField("_sessionFactory"));
67 + il.Emit(OpCodes.Ldarg_0);
68 + il.Emit(OpCodes.Ldfld, fieldBuilder);
63 69 il.Emit(OpCodes.Stloc_0);
64 70
65 71 writeLine(il, "Session got!");
@@ -68,13 +74,15 @@ namespace DatabaseSample {
68 74 il.Emit(OpCodes.Stloc_1);
69 75
70 76 writeLine(il, "Saving session");
77 + il.Emit(OpCodes.Ldarg_0);
71 78 il.Emit(OpCodes.Ldloc_1);
72 - il.Emit(OpCodes.Stsfld, typeof(BaseService).GetField("_session", BindingFlags.NonPublic | BindingFlags.Static));
79 + il.Emit(OpCodes.Stfld, typeof(BaseService).GetField("_session", BindingFlags.Instance | BindingFlags.NonPublic));
73 80 il.Emit(OpCodes.Nop);
74 81
75 - // transaction = BaseService._session.BeginTransaction()
82 + // transaction = _session.BeginTransaction()
76 83 writeLine(il, "Creating Transaction");
77 - il.Emit(OpCodes.Ldsfld, typeof(BaseService).GetField("_session", BindingFlags.NonPublic | BindingFlags.Static));
84 + il.Emit(OpCodes.Ldarg_0);
85 + il.Emit(OpCodes.Ldfld, typeof(BaseService).GetField("_session", BindingFlags.Instance | BindingFlags.NonPublic));
78 86 il.Emit(OpCodes.Call, typeof(ISession).GetMethod("BeginTransaction", new Type[0]));
79 87 il.Emit(OpCodes.Stloc_2);
80 88
@@ -115,11 +123,13 @@ namespace DatabaseSample {
115 123
116 124 // } finally {
117 125 il.BeginFinallyBlock();
118 - // BaseService._session.Close();
126 + // _session.Close();
119 127 writeLine(il, "Closing session");
120 - il.Emit(OpCodes.Ldsfld, typeof(BaseService).GetField("_session", BindingFlags.NonPublic | BindingFlags.Static));
128 + il.Emit(OpCodes.Ldarg_0);
129 + il.Emit(OpCodes.Ldfld, typeof(BaseService).GetField("_session", BindingFlags.Instance | BindingFlags.NonPublic));
121 130 il.Emit(OpCodes.Brfalse_S, exit);
122 - il.Emit(OpCodes.Ldsfld, typeof(BaseService).GetField("_session", BindingFlags.NonPublic | BindingFlags.Static));
131 + il.Emit(OpCodes.Ldarg_0);
132 + il.Emit(OpCodes.Ldfld, typeof(BaseService).GetField("_session", BindingFlags.Instance | BindingFlags.NonPublic));
123 133 il.Emit(OpCodes.Call, typeof(ISession).GetMethod("Close"));
124 134 il.Emit(OpCodes.Pop);
125 135 //}

racerxdl's Avatar Lucas Teske revised this gist 9 years ago. Go to revision

2 files changed, 48 insertions

BaseService.cs(file created)

@@ -0,0 +1,17 @@
1 + using NHibernate;
2 + using System;
3 + using System.Collections.Generic;
4 + using System.Linq;
5 + using System.Text;
6 + using System.Threading.Tasks;
7 +
8 + namespace DatabaseSample {
9 + public class BaseService {
10 + public static ISessionFactory _sessionFactory;
11 + protected static ISession _session = null;
12 +
13 + protected static ISession Session {
14 + get { return _session; }
15 + }
16 + }
17 + }

EmployeeService.cs(file created)

@@ -0,0 +1,31 @@
1 + using DatabaseSample.Models;
2 + using System;
3 + using System.Collections.Generic;
4 + using System.Linq;
5 + using System.Text;
6 + using System.Threading.Tasks;
7 +
8 + namespace DatabaseSample {
9 + public class EmpresaService : BaseService {
10 + public virtual void CriarEmpresas(int n) {
11 + Console.WriteLine("CriarEmpresas({0})", n);
12 + Contato c = new Contato("Lucas Teske", "[email protected]", "Test");
13 +
14 + for (int i = 0; i < n; i++) {
15 + Empresa e = new Empresa();
16 + e.Nome = "TVS" + i;
17 + e.Contato = c;
18 + Session.Save(e);
19 + }
20 + }
21 +
22 + public virtual void lerItems() {
23 + Console.WriteLine("LerItems");
24 + List<Contato> contatos = Session.CreateCriteria<Contato>().List<Contato>().ToList();
25 +
26 + foreach (Contato c in contatos) {
27 + Console.WriteLine("Nome: " + c.Nome);
28 + }
29 + }
30 + }
31 + }

racerxdl's Avatar Lucas Teske revised this gist 9 years ago. Go to revision

1 file changed, 145 insertions

ServiceProducer.cs(file created)

@@ -0,0 +1,145 @@
1 + using NHibernate;
2 + using System;
3 + using System.Collections.Generic;
4 + using System.Linq;
5 + using System.Reflection;
6 + using System.Reflection.Emit;
7 + using System.Text;
8 + using System.Threading.Tasks;
9 +
10 + namespace DatabaseSample {
11 + public static class ServiceProducer<T> {
12 +
13 + public static T ProduceService() {
14 + var myType = CompileResultType<T>();
15 + return (T)Activator.CreateInstance(myType);
16 + }
17 +
18 + public static Type CompileResultType<T>() {
19 + TypeBuilder tb = GetTypeBuilder<T>();
20 + ConstructorBuilder constructor = tb.DefineDefaultConstructor(MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName);
21 +
22 + return tb.CreateType();
23 + }
24 + private static TypeBuilder GetTypeBuilder<T>() {
25 + var typeSignature = "customType_" + typeof(T).Name;
26 + var an = new AssemblyName(typeSignature);
27 + AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(an, AssemblyBuilderAccess.Run);
28 + ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("MainModule");
29 + TypeBuilder tb = moduleBuilder.DefineType(typeSignature
30 + , TypeAttributes.Public |
31 + TypeAttributes.Class |
32 + TypeAttributes.AutoClass |
33 + TypeAttributes.AnsiClass |
34 + TypeAttributes.BeforeFieldInit |
35 + TypeAttributes.AutoLayout
36 + , typeof(T));
37 +
38 + typeof(T).GetMethods().ToList().ForEach(m => {
39 + MethodBuilder mbM = tb.DefineMethod(m.Name, MethodAttributes.Public | MethodAttributes.ReuseSlot | MethodAttributes.Virtual | MethodAttributes.HideBySig,
40 + m.ReturnType,
41 + m.GetParameters().ToList().Select(a => a.ParameterType).ToArray());
42 +
43 + var il = mbM.GetILGenerator();
44 +
45 + il.DeclareLocal(typeof(ISessionFactory));
46 + il.DeclareLocal(typeof(ISession));
47 + il.DeclareLocal(typeof(ITransaction));
48 + il.DeclareLocal(typeof(Exception));
49 + if (!typeof(void).IsAssignableFrom(m.ReturnType)) {
50 + il.DeclareLocal(m.ReturnType);
51 + }
52 +
53 + Label transactionNull = il.DefineLabel();
54 + Label exit = il.DefineLabel();
55 +
56 + // try {
57 + il.BeginExceptionBlock();
58 +
59 + // BaseService._session = BaseService._sessionFactory.OpenSession();
60 + writeLine(il, "GettingSession");
61 + il.Emit(OpCodes.Nop);
62 + il.Emit(OpCodes.Ldsfld, typeof(BaseService).GetField("_sessionFactory"));
63 + il.Emit(OpCodes.Stloc_0);
64 +
65 + writeLine(il, "Session got!");
66 + il.Emit(OpCodes.Ldloc_0);
67 + il.Emit(OpCodes.Call, typeof(ISessionFactory).GetMethod("OpenSession", new Type[0]));
68 + il.Emit(OpCodes.Stloc_1);
69 +
70 + writeLine(il, "Saving session");
71 + il.Emit(OpCodes.Ldloc_1);
72 + il.Emit(OpCodes.Stsfld, typeof(BaseService).GetField("_session", BindingFlags.NonPublic | BindingFlags.Static));
73 + il.Emit(OpCodes.Nop);
74 +
75 + // transaction = BaseService._session.BeginTransaction()
76 + writeLine(il, "Creating Transaction");
77 + il.Emit(OpCodes.Ldsfld, typeof(BaseService).GetField("_session", BindingFlags.NonPublic | BindingFlags.Static));
78 + il.Emit(OpCodes.Call, typeof(ISession).GetMethod("BeginTransaction", new Type[0]));
79 + il.Emit(OpCodes.Stloc_2);
80 +
81 +
82 + // base.{thismethod}({parameters})
83 + writeLine(il, "Calling parent");
84 + il.Emit(OpCodes.Ldarg_0);
85 + UInt16 i = 1;
86 + m.GetParameters().ToList().ForEach(a => {
87 + il.Emit(OpCodes.Ldarg, i);
88 + i++;
89 + });
90 +
91 + il.EmitCall(OpCodes.Call, m, new Type[0]);
92 + if (!typeof(void).IsAssignableFrom(m.ReturnType)) {
93 + il.Emit(OpCodes.Stloc, 4);
94 + }
95 +
96 + // transaction.Commit();
97 + writeLine(il, "Commiting Transaction");
98 + il.Emit(OpCodes.Ldloc_2);
99 + il.Emit(OpCodes.Call, typeof(ITransaction).GetMethod("Commit"));
100 +
101 + // } catch (Exception) {
102 + il.BeginCatchBlock(typeof(Exception));
103 + il.Emit(OpCodes.Pop);
104 +
105 + // transaction.Commit();
106 + writeLine(il, "Rolling back Transaction");
107 + il.Emit(OpCodes.Ldloc_2);
108 + il.Emit(OpCodes.Brfalse_S, transactionNull);
109 + il.Emit(OpCodes.Ldloc_2);
110 + il.Emit(OpCodes.Call, typeof(ITransaction).GetMethod("Rollback"));
111 + writeLine(il, "Exception got!");
112 + il.MarkLabel(transactionNull);
113 + il.Emit(OpCodes.Rethrow);
114 +
115 +
116 + // } finally {
117 + il.BeginFinallyBlock();
118 + // BaseService._session.Close();
119 + writeLine(il, "Closing session");
120 + il.Emit(OpCodes.Ldsfld, typeof(BaseService).GetField("_session", BindingFlags.NonPublic | BindingFlags.Static));
121 + il.Emit(OpCodes.Brfalse_S, exit);
122 + il.Emit(OpCodes.Ldsfld, typeof(BaseService).GetField("_session", BindingFlags.NonPublic | BindingFlags.Static));
123 + il.Emit(OpCodes.Call, typeof(ISession).GetMethod("Close"));
124 + il.Emit(OpCodes.Pop);
125 + //}
126 + il.EndExceptionBlock();
127 +
128 + // return {returndata}
129 + if (!typeof(void).IsAssignableFrom(m.ReturnType)) {
130 + il.Emit(OpCodes.Ldloc, 4);
131 + }
132 +
133 + il.MarkLabel(exit);
134 + il.Emit(OpCodes.Ret);
135 + });
136 +
137 + return tb;
138 + }
139 +
140 + private static void writeLine(ILGenerator il, string line) {
141 + il.Emit(OpCodes.Ldstr, line);
142 + il.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) }));
143 + }
144 + }
145 + }
Newer Older