是的,这是可能的,但是您需要在其中投入一些工作和代码。这是这个想法(未经测试):
创建一个继承BaseEntity
并实现IDynamicMetaObjectProvider的类。然后,您需要构建将函数定义转换为动态属性的函数:
public class DynamicBreezeEntity : BaseEntity, IDynamicMetaObjectProvider
{
private readonly Dictionary<string, PropertyDefinition> _properties;
public DynamicBreezeEntity ()
{
_properties = new Dictionary<string, PropertyDefinition>();
}
public void DefineProperty(string name, Type type, bool isNullable = false)
{
if (string.IsNullOrEmpty(name))
throw new ArgumentNullException("name");
if (_properties.ContainsKey(name))
throw new ArgumentException("Property already defined.", "name");
if (type == null)
throw new ArgumentNullException("type");
if (isNullable && !type.IsValueType)
throw new ArgumentException("Only value types can be nullable.", "type");
if (isNullable)
{
type = Nullable.GetUnderlyingType(type);
if (type.IsValueType)
type = typeof(Nullable<>).MakeGenericType(type);
}
_properties.Add(name, new PropertyDefinition { Type = type });
}
public object GetValue(string name)
{
PropertyDefinition def;
if (_properties.TryGetValue(name, out def))
return def.Value;
throw new ArgumentException("Property not defined.", "name");
}
public void SetValue(string name, object value)
{
// more work todo here: handle value == null correctly
PropertyDefinition def;
if (_properties.TryGetValue(name, out def) && def.Type.IsAssignableFrom(value.GetType()))
def.Value = value;
throw new ArgumentException("Property not defined.", "name");
}
public IEnumerable<string> GetPropertyNames()
{
return _properties.Keys.ToList();
}
DynamicMetaObject IDynamicMetaObjectProvider.GetMetaObject(Expression parameter)
{
return new Proxy(this);
}
private class PropertyDefinition
{
public Type Type { get; set; }
public object Value { get; set; }
}
private class Proxy : DynamicMetaObject
{
public Proxy(DynamicBreezeEntity host, Expression expression)
: this(host, expression, BindingRestrictions.Empty) { }
public Proxy(DynamicBreezeEntity host, Expression expression, BindingRestrictions restrictions)
: base(expressiom restrictions, host) { }
private DynamicBreezeEntity Host
{
get { return (DynamicBreezeEntity)Value; }
}
private BindingRestrictions GetBindingRestrictions()
{
var restrictions = BindingRestrictions.GetTypeRestriction(this.Expression, this.LimitType);
return restrictions.Merge(BindingRestrictions.GetInstanceRestriction(this.Expression, this.Host));
}
public override IEnumerable<string> GetDynamicMemberNames()
{
return this.Host.GetPropertyNames();
}
public override DynamicMetaObject BindGetMember(GetMemberBinder binder)
{
var arguments = new Expression[] { Expression.Constant(binder.Name) };
var method = typeof(DynamicBreezeEntity).GetMethod("GetValue");
var callExpression = Expression.Convert(Expression.Call(Expression.Convert(this.Expressiom, this.LimitType), method, arguments), binder.ReturnType);
return new DynamicMetaObject(callExpression, GetBindingRestrictions());
}
public override DynamicMetaObject BindSetMember(SetMemberBinder binder, DynamicMetaObject value)
{
var arguments = new Expression[] {
Expression.Constant(binder.Name),
Expression.Convert(value.Expression, typeof(object))
};
var method = typeof(DynamicBreezeEntity).GetMethod("SetValue");
return new DynamicMetaObject(
Expression.Call(Expression.Convert(this.Expression, this.LimitType), method, arguments),
this.GetBindingRestrictions()
);
}
}
}
我不知道微风,BaseEntity
可能有你需要实现的抽象属性/方法。我没有专注于此。
您现在可以用作
var breeze = new DynamicBreezeEntity();
breeze.DefineProperty("Id", typeof(Int32));
dynamic dynBreeze = breeze;
dynBreeze.Id = "Foo";
Console.WriteLine("Id: {0}", dynBreeze.Id);
代码可能不完整(目前没有 VS 访问权限),但应该为您指明正确的方向。