我应该使用反射来计算两个或更多实体中存在的属性吗?

问题描述 投票:0回答:1

目标

我希望能够计算在许多不同的数据库实体中使用特定PrimaryImageId的次数。

他们的每个类都有一个PrimaryImageId属性,并装饰有[HasPrimaryImage]属性。他们还实现了一个接口IHasPrimaryImage

我可能事先不知道这些类,所以我想使用[HasPrimaryImage]属性来识别它们,而不是类型中的硬代码。

我试过了

我正在使用通用存储库方法。但是,虽然它在使用“硬编码”类型调用时有效:

GetCount<NewsItem>(x => x.PrimaryImageId == id);

...当反射提供类型参数时,我无法使它工作。

var types = GetTypesWithHasPrimaryImageAttribute();
foreach(Type t in types)
{
    GetCount<t>(x => x.PrimaryImageId == id);
}

我试过调用GetCount<t>()GetCount<typeof(t)>和其他一些愚蠢的东西。

似乎I can't call a generic method使用反射生成type

Jon Skeet recommends在他的回答中使用了MakeGenericMethod,但我很难做到这一点并且想知道这对我的要求是否有点过分。是否有更简单/更好的方式来实现我追求的目标?



Db实体类

[HasPrimaryImage]
public class NewsItem 
{
    public int PrimaryImageId { get; set; }

    // .. other properties
}


[HasPrimaryImage]
public class Product 
{
    public int PrimaryImageId { get; set; }

    // .. other properties
}

通用存储库方法

public virtual int GetCount<TDataModel>(Expression<Func<TDataModel, bool>> wherePredicate = null)
    where TDataModel : class, IDataModel
{
    return GetQueryable<TDataModel>(wherePredicate).Count();
}

使用HasPrimaryImage属性获取所有类:

public static IEnumerable<Type> GetTypesWithHasPrimaryImageAttribute()
{
    var currentAssembly = Assembly.GetExecutingAssembly();
    foreach (Type type in currentAssembly.GetTypes())
    {
        if (type.GetCustomAttributes(typeof(HasPrimaryImageAttribute), true).Length > 0)
        {
            yield return type;
        }
    }
}   
c# generics reflection repository
1个回答
1
投票

如果你已经获得了MethodInfo,那么在通过反射进行调用之前,你可以使用它的MakeGenericMethod方法来指定它的泛型类型参数。

MethodInfo getCountMethod = my Objectives. GetType() .GetMethod(
    "GetCount", 
    BindingFlags.Public | BindingFlags.Instance | ...); // Fill the right flags

var types = GetTypesWithHasPrimaryImageAttribute();
Func<Entity, bool> predicate = x => x.PrimaryImageId == id;

foreach(Type t in types)
{
     getCountMethod.MakeGenericMethod(type).Invoke(myObj, predicate);
}

我无法运行此代码,所以请原谅我,如果有一些遗漏。但这应该是工作原则,你将能够使它适合你。

© www.soinside.com 2019 - 2024. All rights reserved.