我实现了通用存储库模式和单元工作。我使用了基本模式,效果很好。在项目中我有要求说,每个表都有几个字段,其中包含很长很长的文本,用户应该有能力选择并打开任何一个。由于每个字段的名称不同,我决定使用带有反射的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”。 我找不到如何识别实现类的类型,并解决了这个问题。任何帮助都是适当的
答案 0 :(得分:0)
我不确定这是最佳选择,但是使用here的ToExpando()扩展程序解决了问题。通过此扩展,我可以循环抛出unitofwork的所有属性,并按名称查找所需的属性。
# Create your views here.
import pandas as pd
from flask import Flask
from flask import request
app = Flask(__name__)
@app.route('/getfields',methods=['GET','POST'])
def getfields(request):
df = pd.read_excel('C:\Users\mysite\Rules.xls')
allfields = df['Field_Name'].unique()
if request.method == 'GET':
return render_template('page1.html',allfields=allfields)
elif request.method == 'POST':
dropValue = request.form.get(['fieldnames'])
dfrows = df.loc[df['Field_Name']==dropValue]
return render_template('page1.html',allfields=allfields,dfrows=dfrows[['rule','rule_type']].to_html())
if __name__ == "__main__":
app.run()
html code:
<!doctype html>
<title>Hello from Flask</title>
<h1>Hello {{ allfields }}!</h1>
<form action="/getfields" method='post'>
<select name='fieldnames'>
{% for val in allfields %}
<option value='{{val}}'>{{val}}</option>
{% endfor %}
</select>
{{dfrows}}
<input type='submit' value='submit'>
</form>
现在方法正在调用。可能有更清洁的解决方案,我仍然希望找到这个。现在我将使用这个解决方案,并且意识到我必须阅读并练习很多关于反射,动力学和泛型的知识。 P.S特别感谢Alexei提供了重要的注释和建议