Hi everyone,
I am trying to achieve something similar to the .NET Entity Framework, meaning to proxy an existing class such as a basic data model, and extend it with some specific code.
There are several ways to do this, but after several tests, I came to the conclusion that, in my specific use case, the fastest solution, by far, was using Reflection.Emit. As a matter of fact, using the latter, I can instantiate an entity in about 0.03ms which
is far better than the 0.89ms I could achieve by using a combinaison of the RealProxy and the System.Dynamic classes.
I am however facing a major challenge, which I will try to explain with a simple exemple:
The user-defined data model:
public class Client
{
[DataMember]
public virtual Guid Id{get;set;}
[DataMember]
public virtual string FirstName{get;set;}
[DataMember]public virtual string LastName{get;set;}
}
The proxied data model, generated thanks to Relfection.Emit:
: Client, INotifyPropertyChanged
{
private Guid _Id;
private Guid _FirstName;
public virtual Guid Id
{
get
{
return _Id;
}
set
{
_Id = value;
if(this.PropertyChanged != null)
{
this.PropertyChanged("Id");
}
}
}
public virtual string FirstName
{
get
{
return _FirstName;
}
set
{
_FirstName = value;
if(this.PropertyChanged != null)
{
this.PropertyChanged("FirstName");
}
}
}
public virtual string LastName
{
get
{
return _LastName;
}
set
{
_LastName = value;
if(this.PropertyChanged != null)
{
this.PropertyChanged("LastName");
}
}
}
}
The challenge:
How can I replace an instance of the Client class by an instance of the ClientProxy class, at runtime?
I tried making both the Client and the ClientProxy (renamed Client for the occasion) classes 'partial', but I would get an exception stating that Type[A] (Client) differs from Type[B] (ClientProxy). I take it throws this exception because the partial Client
class generated with Emit is not from the same assembly as the data model.
I googled for a way to "inject" my dynamic type into the assembly defining the Client data model for the exception not to be thrown again, but this seems impossible via Emit.
How can I achieve this? It must be possible via Emit, for I believe this is the way the EntityFramework does the trick, am I wrong?
If I am wrong, what are my options? CLR injection?
Thanks in advance for your time and attention,
Chad