2

Hi i'm writing a simple ORM DLL. The library works fine and i would like add some addone - Lazy Loading. But i don't know how to implements that. I have one proposition.

In my orm (i have creator but never mind) User should create DB class who implements IMapper and set mapper class. Somethink linke this.

public class Person
{
  public virtual string Name {get;set;}
  public virtual int Age {get; set;}
}

public class DataBase : IMapper
{
  MapperSet<Person> Persons = new MapperSet<Person>();
}

If we have that class, and setup connectionString, we can take the data from DB. It's very similar to Entity Framework

Person p = Persons.Single(x=>x.Name == "John");

In that moment, i will check the all properties in mapping class and if are virtual then not return a that class, but Lazy Loading class. I think out one conception. Not return (in that example) Person class but the class who extends Person class, and override all properties.

public class PersonReturn : Person
{
  //here i must create a method who really take the data from db
  private string Query = "SELECT TOP(1) FROM Person WHERE Name = 'John'";
  private Execute()
  {
    p = (Person)Db.TableToObject(Query);
  }
  Person p;

  public override string Name 
  {
   get
   {
     if(p == null)
      p = Execute();

    return p.Name;
   }
   set {}
   }

  //same
  public override int Age {get; set;}
}

User shouldn't see any change with using that class (only in debug it maybe see other class) it's should work as magic :P

My questions are : 1. How is implement Lazy Loading in for example Entity Framework, anybody know ? 2. Is simpler way from my proposition ? In my idea i must use TypeBuilder and Emit with IL source code - i hear it's problems with properties they aren't be use in normaly way.

2 Answers 2

1

Use Castle.DynamicProxy (same proxy that nhibernate uses)

Sign up to request clarification or add additional context in comments.

Comments

0

Lazy loading is implemented by generating inheritor at runtime and override all methods.

public class A
{
    virtual protected string name { get; set; }
}

public interface IInterceptor
{
    object Invoke(MethodInfo method, params object[] arguments);
}

public sealed class AProxy : A
{
    static private readonly MethodInfo getname = typeof(A).GetProperty("name", ...).GetGetMethod(true);
    static private readonly MethodInfo setname = typeof(A).GetProperty("name", ...).GetSetMethod(true);

    private readonly IInterceptor interceptor;

    public AProxy(IInterceptor interceptor)
    {
        this.interceptor = interceptor;
    }

    override protected string name
    {
        get { return this.interceptor.Invoke(AProxy.getname); }
        set { this.interceptor.Invoke(AProxy.setname, value); }
    }
}

Proxy factory have to to

return new AProxy(custominterceptor);

custominterceptor must take id of your entity and in first usage instantiate A, query database to populate A and delegate call to A.

AProxy must be generated (postbuild or at runtime using TypeBuilder)

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.