我正在开发一个需要使用BreezeSharp处理动态对象的项目。我通过JSON文件接收对象的结构,例如:
[{
name: 'Admin',
serviceAddress: 'http://abcd.com/breeze/admins',
dataProperties: {
Id: { type: breeze.DataType.Int32 },
Title: { nullable: true },
ContentTypeId: {},
Created: { type: breeze.DataType.DateTime },
Modified: { type: breeze.DataType.DateTime },
File: { complexType: 'Document:#File' },
},
{
name: 'Car',
serviceAddress: 'http://abcd.com/breeze/cars',
dataProperties: {
Id: { type: breeze.DataType.Int32 },
Model: { nullable: true },
Created: { type: breeze.DataType.DateTime },
Modified: { type: breeze.DataType.DateTime },
}]
我希望自动生成从Breeze.Sharp.BaseEntity继承的对象,并列出属性。
我还必须在创建动态对象后创建breeze实体管理器。
我之所以需要这个,是因为我有一个使用BreezeJS的SharePoint应用程序。这些实体基于那里的JSON文件。
所以我想创建一个桌面应用程序,它将使用基于JSON文件的相同实体。我不确定是否可以创建继承BaseEntity类的动态对象。
答案 0 :(得分:2)
是的,这是可能的,但你需要将一些工作和代码放入其中。 这是一个想法(未经测试):
创建一个继承自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()
);
}
}
}
我不知道Breeze,BaseEntity
可能有你需要实现的抽象属性/方法。我没有专注于那个。
您现在可以使用
var breeze = new DynamicBreezeEntity();
breeze.DefineProperty("Id", typeof(Int32));
dynamic dynBreeze = breeze;
dynBreeze.Id = "Foo";
Console.WriteLine("Id: {0}", dynBreeze.Id);
代码可能不完整(目前没有VS访问权限),但应指向正确的方向。