调用数据访问层的泛型方法
本文关键字:泛型方法 访问 数据 调用 | 更新日期: 2023-09-27 18:14:29
我正在创建一个具有三层架构的应用程序。
- UI (web)
- BLL (ClassLibrary)
- 木豆(ClassLibrary)
我的需要是绑定下拉列表,如角色,城市,国家,州等
我已经为所有实体创建了属性(所有将具有相同的结构),如
public class City
{
public string Id { get; set; }
public string Name { get; set; }
}
考虑下面的控制台应用程序示例,它复制了我的需求
假设这个调用来自我的UI
static void Main( string[] args )
{
List<City> cities = GetDataList<City>();
List<Role> roles = GetDataList<Role>();
}
这是我的业务逻辑(BLL)
public static List<T> GetDataList<T>() where T:class ,new()
{
List<T> list = new List<T>();
(A) List<T> data = ** I am not getting the way how to call different methods of data acess here?
foreach (var temp in data.AsEnumerable())
{
var obj = new T();
( B) foreach (var prop in obj.GetType().GetProperties())
{
var propertyInfo = obj.GetType().GetProperty(prop.Name);
propertyInfo.SetValue(obj , Convert.ChangeType(temp. , propertyInfo.PropertyType) , null);
}
list.Add(obj);
}
return list;
}
这是我的数据访问层,我在这里使用EF
public static IList<City> FetchCityData()
{
List<City> dict = new List<City>();
dict.Add(new City{Id="1",Name="hello"});
dict.Add(new City{Id="2",Name="world"});
return dict;
}
public static List<Role> FetchStateData()
{
List<Role> dict = new List<Role>();
dict.Add(new Role { Id = "1" , Name = "hello" });
dict.Add(new Role { Id = "2" , Name = "world" });
return dict;
}
My Questions Are:
A)如何从BLL访问不同的dataaccess方法?
B)我将如何赋值给我的类属性在这里?
A和B是代码中的标签
你最好的选择是分支代码。然而,你可以通过在helper类中声明一些Dictionary<Type, Func<object>>
来使它更整洁,像这样:
public static class DataFetcher {
static Dictionary<Type, Func<object>> _fetchers;
static Dictionary<Type, Func<object>> Fetchers {
get {
if(_fetchers == null) _fetchers = new Dictionary<Type, Func<object>>();
return _fetchers;
}
}
static DataFetcher(){
Fetchers[typeof(City)] = FetchCityData;
Fetchers[typeof(State)] = FetchStateData;
}
public static IList<T> FetchData<T>(){
Func<object> f;
if(Fetchers.TryGetValue(typeof(T), out f)){
return (IList<T>) f();
}
return null;
}
}
使用:
public static List<T> GetDataList<T>() where T:class ,new()
{
var data = DataFetcher.FetchData<T>();
//...
}
还是不明白你的第二个要求
实际上,你的DAL设计是错误的。
如果你的业务层中有很多这样的泛型调用,你应该在你的DAL中公开泛型数据访问器(如果你使用EF,这是简单明了的)。
这意味着
-
您应该为这些项目建立一个公共接口,例如
public interface IReferenceData { string Id { get; set; } string Name { get; set; } }
-
你应该公开通用方法来获取它
public IEnumerable<T> GetReferenceData<T>() where T: IReferenceData
这样你的BLL就会像
一样简单public static List<T> GetDataList<T>() where T: IReferenceData
{
return Dal.GetReferenceData<T>().ToList()
}
(尽管在这种情况下不需要BLL)
Update:实际上,您不需要接口,我只是习惯这样做,以便我可以添加一些处理到BLL。这个问题不需要它
首先,您可以轻松地在应用程序中引入Repository模式。记住,Repository是域层(BLL)中的接口,在基础设施层(DAL)中实现。通用存储库通常有一个基类,它封装了所有实体和标识(键)类型的所有基本CRUD操作。
然后您可以使用依赖注入库(领域层中的存储库接口)将接口绑定到实现,或者甚至更好,创建应用层,它的契约(接口)将是您的用例,而实现将是粘合代码,它将域和基础结构代码绑定在一起以执行所述用例。阅读更多关于领域驱动设计的内容。
也就是说,有一种更现代的方式来与存储交互——实现命令&查询隔离。其中所有的数据读取都是查询,写入都是命令。它们都有一个通用的基础,封装了大量的逻辑。而不是存储库,它会被很多方法膨胀,你会得到很多单独的命令&(希望)更容易管理的查询类。
看一看提供的链接,这不是火箭科学,实际上,所有的部分都很容易适应一个大的图片随着时间的推移。
您可以使用反射来获取数据层类型并使用MethodInfo。调用通过字符串名称调用方法,使用所需返回类型的类型名称。我做了一个简短的例子,但由于我在手机上,所以无法进行测试!
Type dalType = Type.GetType("dalnamespace")
MethodInfo methodInfo = dalType.GetMethod(string.Format("Fetch{0}Data", objectTypeStringHere));
var returnValue = (List<T>)methodInfo.Invoke(dalType, null);