繁体   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