(assuming we're still talking about formulae properties)
Fair enough, but you still need to get hold of the new types and create
instances of them. When I have done similar, I have found that the best
approach is actually a generics-trick (see below), since you then don't
need any reflection (except for the initial startup). The only other
options involve some kind of factory, or getting hold of the
ConstructorInfo instances everywhere.
I need extensible entity classes.
I do'nt understand how your trick can be used to extend Customer
class with new properties. I tried code below but this causes NRE.
So I'm planning to use the following:
1. For application design, create unsigned entity assembly containing common
methods.
public class Customer : EntityBase<Customer> {
string id;
public string Id {
get {
return id;
}
set {
id = value;
}
}
}
This assembly is referenced from projects and allows to use all standard
properties and methods.
2. At application startup, create fully Customer class assembly from table
structure containing
(if user adds) additional properties like
public class Customer: EntityBase<Customer> {
string id;
public string Id {
get {
return id;
}
set {
id = value;
}
}
string name;
public string Name {
get {
return name;
}
set {
name = value;
}
}
public string FullName {
get {
return "Mr " + Name;
}
}
}
and replace dll file in disk with this new file.
3. Now .NET if foolished and it loads the new assembly at runtime expecting
that this is original assembly shipped with application.
This does not require to use any reflection calls.
But again, I strongly warn against taking user-entered formulae and
compiling into code! To me, this would rank right up there with
"&admin=false" (as a web-page query-string), or SQL-injection
vulnerability.
I'm creating client-server desktop application which runs in client side.
Client can crack this application in any way. Yes, it can corrupt his/her
local computer and corrupt his data in server.
However, client has acces to his computer and to his data anyway and can
corrupt them in any other ways also.
SQL Server asks from user/name password and allows to acces only authorized
data at protocol level. There is no way to use this application for
unauthorized access to restriced resources in server. So I do'nt see ANY
vulnerabilites here. I recommend user to backup data before changing
formulas.
If you are only referring to regular value properties (a user-defined
DateTime called "DateOfBirth", etc), then you can do this without all the
messing. Putting together a runtime-extensible (property-bag) class isn't
actually all that hard. I have posted examples to this forum several
times. TypeDescriptionProvider is probably the way to go in such a case,
but it can't handle text formulae unless you bolt a parser onto the end.
How to create TypeDescriptionProvider which compiles poperty expression to
static method and executes it in the fly?
This would be good solution which allows creating dynamic assemblies only
for extensible properites.
Code causing NRE:
using System;
using System;
using System.Reflection;
static class Program {
static void Main() {
// would actually be from dynamic assembly
Assembly dynamicAssembly = Assembly.GetExecutingAssembly();
// get the user's type
Type dynamicType = dynamicAssembly.GetType("CustomerExtension");
// find generic SomeBodyOfCode
MethodInfo mi = typeof(Program).GetMethod(
"EntityBase",
BindingFlags.Static | BindingFlags.NonPublic);
// get constructed closed SomeBodyOfCode
mi = mi.MakeGenericMethod(dynamicType);
// invoke
mi.Invoke(null, null);
// Need to create customer object containing properties
// and methods defined in runtime.
Customer Customer = new Customer();
// set dynamic property, called from DataGridView PushCellValue
Customer.SetValue("Name", "Marc");
}
}
// from core library
public class Customer : EntityBase<Customer> {
string id;
public string Id {
get {
return id;
}
set {
id = value;
}
}
}
// from core library
public abstract class EntityBase<T> {
public virtual void SetValue(string propertyName, string propertyValue) {
PropertyInfo p = GetType().GetProperty(propertyName);
p.SetValue(this, propertyValue, null);
}
}
// from dynamic library
public class CustomerExtension : Customer {
string name;
public string Name {
get {
return name;
}
set {
name = value;
}
}
public string FullName {
get {
return "Mr " + Name;
}
}
}