0

我正在尝试做的是概括使用 AutoFixture 和 Moq 制作存储库。我有一个名为“添加”的方法,可以将虚假记录添加到列表中。该列表称为记录,对类是全局的。通用 M 是要模拟的模型。该方法返回“this”,因此可以链接该方法。

public Repo<M> add(string prop, string val) {
    var a = fixture.Build<M>().With(m => m.GetProperty(prop), val).Create();
    records.Add(a);
    return this;
}

使用扩展类(我发现这个搜索 SO):

public static class MyExtensions
{
    public static object GetProperty<T>(this T obj, string name) where T : class
    {
        Type t = typeof(T);
        return t.GetProperty(name).GetValue(obj, null);
    }
}

我得到的错误是“Ploeh.AutoFixture.dll 中发生 ArgumentException”。

我的问题是:当模型在编译时未知时,如何将通用对象的属性作为参数传递给方法?

4

2 回答 2

4

With方法需要Expression<Func<T, TProperty>>参数 not PropertyInfo

您可以将add方法更改为 takeExpression<Func<T, TProperty>>而不是 string :

public Repo<M> add<T>(Expression<Func<M, T>> propertyPicker, T val) 
{
   var a = fixture.Build<M>().With(propertyPicker, val).Create();
   records.Add(a);
   return this;
}

这是用法:

add(foo => foo.Name, "abc");
于 2015-09-11T17:45:17.010 回答
0

非常感谢 Arkadiusz 的正确答案。我只想添加我添加的这个方法(受几个 SO 帖子的启发)来创建表达式,以便使用如下: add("username","me")

private Expression<Func<M,T>> makeExpression<T>(string prop, T val)
{
    var m = Expression.Parameter(typeof(M), "m");
    Expression columnExpr = Expression.Property(m,typeof(M).GetProperty(prop));

    return Expression.Lambda<Func<M, T>>(columnExpr, m);
}

然后,在 add 方法中,我更改propertyPickermakeExpression(property,val)property作为字符串的属性名称。

于 2015-09-11T22:33:23.520 回答