Skip to content

Instantly share code, notes, and snippets.

@hoangitk
Created September 19, 2014 06:49
Show Gist options
  • Save hoangitk/7a53968d58ccd7fe6408 to your computer and use it in GitHub Desktop.
Save hoangitk/7a53968d58ccd7fe6408 to your computer and use it in GitHub Desktop.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Dynamic;
using System.Linq;
using System.Text.RegularExpressions;
using Castle.ActiveRecord;
using Castle.ActiveRecord.Framework.Config;
using log4net.Config;
using NHibernate;
using NHibernate.Criterion;
using NUnit.Framework;
namespace NHDynamicTests {
[TestFixture]
public class DynamicTests {
[Test]
public void DynamicGetPersonByName() {
using (ISession s = ActiveRecordMediator.GetSessionFactoryHolder().GetSessionFactory(typeof(object)).OpenSession()) {
dynamic ds = s.AsDynamic();
Person person = ds.GetPersonByName("pepe");
}
}
[ActiveRecord]
public class Person {
[PrimaryKey]
public int Id { get; set; }
[Property]
public string Name { get; set; }
}
[TestFixtureSetUp]
public void FixtureSetup() {
BasicConfigurator.Configure();
var arConfig = new InPlaceConfigurationSource();
var properties = new Dictionary<string, string> {
{"connection.driver_class", "NHibernate.Driver.SQLite20Driver"},
{"dialect", "NHibernate.Dialect.SQLiteDialect"},
{"connection.provider", "NHibernate.Connection.DriverConnectionProvider"},
{"connection.connection_string", "Data Source=test.db;Version=3;New=True;"},
};
arConfig.Add(typeof(ActiveRecordBase), properties);
ActiveRecordStarter.ResetInitializationFlag();
var arTypes = GetType().GetNestedTypes()
.Where(t => t.GetCustomAttributes(typeof(ActiveRecordAttribute), true).Length > 0)
.ToArray();
ActiveRecordStarter.Initialize(arConfig, arTypes);
ActiveRecordStarter.CreateSchema();
}
}
public static class ISessionExtensions {
public static dynamic AsDynamic(this ISession session) {
return new DynamicSession(session);
}
}
public class DynamicSession : DynamicObject {
private readonly ISession session;
public DynamicSession(ISession session) {
this.session = session;
}
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result) {
result = null;
if (!binder.Name.StartsWith("Get"))
return false;
var tokens = Regex.Replace(binder.Name, "([A-Z])", " $1").Split(' ').Skip(1).ToArray();
if (tokens.Length < 4 || args.Length < 1)
return false; // some parameter is missing
var typeName = tokens[1];
var type = session.SessionFactory.GetAllClassMetadata()
.Cast<DictionaryEntry>()
.Select(e => e.Key).Cast<Type>()
.FirstOrDefault(t => t.Name == typeName);
if (type == null)
throw new ApplicationException(string.Format("Type '{0}' is not mapped in NHibernate", typeName));
var fieldName = tokens[3];
var criteria = DetachedCriteria.For(type).Add(Restrictions.Eq(fieldName, args[0]));
result = criteria.GetExecutableCriteria(session).UniqueResult();
return true;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment