[英]Invoke method from base class using reflection
我實現了通用存儲庫模式和單元工作。 我使用了基本模式,效果很好。 在項目中我有要求說,每個表都有幾個字段,其中包含很長很長的文本,用戶應該有能力選擇並打開任何一個。 由於每個字段的名稱不同,我決定使用帶有反射的power ov泛型,編寫釋放表名和字段名並返回它的方法。 方法,在通用的Repository類中,我寫的看起來像這樣,看起來工作正常
public interface IRepository<T> where T : class
{
//other methods
string GetPropertyByName(int id, string property);
}
public class Repository<T> : IRepository<T> where T : class
{
// other methods. add, edit, delete...
public string GetPropertyByName(int id, string property)
{
T model = this.Get(id);
var obj = model.GetType().GetProperty(property).GetValue(model, null);
return obj != null ? obj.ToString() : null;
}
}
我用幫助EF為表創建了模型類。 有些表直接綁定genric存儲庫,而其他表有單獨的接口及其實現,因為它們需要額外的方法。 例:
public interface ICompanyRepo : IRepository<COMPANY>
{
//some methods
}
public class CompanyRepo : Repository<COMPANY>, ICompanyRepo
{
//implementations of interface methods
}
和UOW實施:
public interface IUnitOfWork
{
ICompanyRepo Company { get; }
IRepository<CURRENCY> Currency { get; }
}
public class UnitOfWork : IUnitOfWork
{
static DBEntities _context;
private UZMEDEXPORTEntities context
{
get
{
if (_context == null)
_context = new DBEntities();
return _context;
}
}
public UnitOfWork()
{
_context = context;
Company = new SP_CompanyRepo();
Currency = new Repository<CURRENCY>();
}
public ICompanyRepo Company { get; private set; }
public IRepository<CURRENCY> Currency { get; private set; }
}
我在業務層中調用GetPropertyByName()方法時遇到問題。 我試過這個:
public string GetHistory(string tableName, string fieldName, int id)
{
var prop = unitOfWork.GetType().GetProperty(tableName);
MethodInfo method;
method = prop.PropertyType.GetMethod("GetPropertyByName"); //try to find method
if(method == null) //if method not found search for interface which contains that method
method = prop.PropertyType.GetInterface("IRepository`1").GetMethod("GetPropertyByName");
var res = method.Invoke(prop, new object[] { id, fieldName });
return (string)res;
}
返回System.Reflection.TargetException。 據我所知,問題是單位工作實施。 在我的invoke方法中,“prop”是接口類型(ICompanyRepo),但是invoke的目標應該是接口實現類,在本例中為“CompanyRepo”。 我找不到如何識別實現類的類型,並解決了這個問題。 任何幫助都是適當的
我不確定這是最好的選擇,但是使用這里給出的ToExpando()擴展解決了問題。 使用此擴展,我可以循環拋出unitofwork的所有屬性,並通過其名稱查找所需的屬性。
var propValue = unitOfWork.ToExpando().Single(x => x.Key == prop.Name).Value;
var res = method.Invoke(propValue, new object[] { id, fieldName });
現在方法正在調用。 可能有更清潔的解決方案,我仍然希望找到這個。 現在我將使用這個解決方案,並且意識到我必須閱讀並練習很多關於反射,動力學和泛型的知識。 PS特別感謝Alexei提供的重要說明和建議
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.