簡體   English   中英

使用反射從基類調用方法

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM