C# 动态泛型实例
C# Dynamic generic instance
这是我的第一个问题,我对 C# 术语不是很熟悉,所以如果我混淆了一些术语或定义,我提前表示歉意。
我已经设置了一个通用的 EF 数据访问层;
public class BaseService<TObject> where TObject : class
{
private DbContext Context;
private static readonly Lazy<BaseService<TObject>> lazy = new Lazy<BaseService<TObject>>(() => new BaseService<TObject>());
public static BaseService<TObject> Instance => lazy.Value;
public BaseService()
{
Context = new evEntities();
}
public BaseService(DbContext context)
{
Context = context;
}
public ICollection<TObject> GetAll()
{
return Context.Set<TObject>().ToList();
}
public async Task<ICollection<TObject>> GetAllAsync()
{
return await Context.Set<TObject>().ToListAsync();
}
public TObject Get(int id)
{
return Context.Set<TObject>().Find(id);
}
}
连同这个;
public static class DA
{
public static DataAccess.Categories Categories => new DataAccess.Categories();
public static DataAccess.Tags Tags => new DataAccess.Tags();
public static DataAccess.Users Users => new DataAccess.Users();
}
public static class DA<T> where T : class
{
public static BaseService<T> Base => new BaseService<T>();
}
所以在我的业务层我可以做到这一点;
public class Categories
{
public Categories() { }
public ICollection<Database.Categories> GetAll()
{
return DA.Categories.GetAll().ToList();
}
public async Task<ICollection<Database.Categories>> GetAllAsync()
{
return await DA.Categories.GetAllAsync();
}
public Database.Categories Get(int id)
{
return DA.Categories.Get(id);
}
}
为清楚起见。我的 EF 创建了 classes/entities,比如 'Database.Categories' 和 'Database.Users',我将它们作为 'TObject' 传递给我的 BaseService,以获得拉取数据的标准方式来自我所有实体的数据库。
现在我的问题。我想以类似的方式创建一个通用的业务层。喜欢;
public class BusinessLogicBase<TModel>
{
public ICollection<TDBModel> GetAll()
{
return null;
}
public async Task<ICollection<TDBModel>> GetAllAsync()
{
return await DA.Categories.GetAllAsync();
}
public TDBModel Get(int id)
{
return DA.Categories.Get(id);
}
}
我希望能够使用类似 Database.Categories 的 TObject 调用 DA,但这必须是动态的,基于传递给 BusinessLogicBase 的类型。所以我想做这样的事情(这是行不通的);
private ???? DetermineDatabaseModel()
{
switch(typeof(TModell))
{
case Models.Categories:
return Database.Categories;
case Models.Users:
return Database.Users;
}
}
所以我可以做到;
public ICollection<TDBModel> GetAll()
{
var databaseModel = DetermineDatabaseModel()
return DA<databaseModel>().GetAll();
}
希望你能理解我的问题并能帮助我。
谢谢!
抱歉拖了这么久 post,对于所有 9gaggers,这里有一个土豆...不是开玩笑,这是认真的。
你有没有尝试过类似的东西:
public class BusinessLogicBase<TDBModel> where TDBModel : class {
public ICollection<TDBModel> GetAll() {
return DA<TDBModel>.Base.GetAll();
}
}
更新 1:
如果您先尝试在不使用泛型的情况下编写它,然后使用泛型将其转换为更通用的模式,也许会对您有所帮助。如果没有泛型,有些错误更容易解决。
方法 public ICollection<TDBModel> GetAll()
不能 return ICollection<TDBModel>
因为类型参数 TDBModel
未在 class 签名或方法签名中定义。如果你这样定义它更有意义:
public class BusinessLogicBase<TModel>
{
public ICollection<TModel> GetAll()
{
return null;
}
}
更新 2:
尝试 this simple console app 演示 dynamic
关键字并观察存储在变量 categories
和 users
.
中的内容
更新 3:
基于 fiddle - 我已将 IBaseService<dynamic>
更改为 dynamic
:
public class BL<TModel>
{
// This is what i want to make dynamic.
// how do i create a return type that i can use in DA<>..
private Type testDetermineDatabaseModel()
{
switch(typeof(TModel).Name){
case "Categories":
return typeof(Database.Categories);
case "Users":
return typeof(Database.Users);
}
return null;
}
public ICollection<TModel> testGetAll()
{
var databaseModel = testDetermineDatabaseModel();
// return DA<databaseModel>().Base.GetAll();
return new List<TModel>();
}
// NEW
// I have constructed the following.
private dynamic baseService;
public dynamic DetermineDatabaseModel()
{
switch (typeof(TModel).Name)
{
case "Categories":
return new BaseService<Database.Categories>();
case "Users":
return new BaseService<Database.Users>();
default:
return null;
}
}
private IBaseService<TDbModel> GetBase<TDbModel>() where TDbModel : class
{
return new BaseService<TDbModel>();
}
public ICollection<TModel> GetAll()
{
ICollection<TModel> returnValue = new List<TModel>();
// This works!!!
foreach (var item in GetBase<Database.Categories>().GetAll())
{
returnValue.Add((TModel)(object)item);
}
baseService = DetermineDatabaseModel();
// This doesn't!!! It's the same thing!! :(
foreach (var item in baseService.GetAll())
{
returnValue.Add((TModel)(object)item);
}
return returnValue;
}
}
但请记住,这并不能解决您面临的问题。即 map 2 通用类型。
这是我的第一个问题,我对 C# 术语不是很熟悉,所以如果我混淆了一些术语或定义,我提前表示歉意。
我已经设置了一个通用的 EF 数据访问层;
public class BaseService<TObject> where TObject : class
{
private DbContext Context;
private static readonly Lazy<BaseService<TObject>> lazy = new Lazy<BaseService<TObject>>(() => new BaseService<TObject>());
public static BaseService<TObject> Instance => lazy.Value;
public BaseService()
{
Context = new evEntities();
}
public BaseService(DbContext context)
{
Context = context;
}
public ICollection<TObject> GetAll()
{
return Context.Set<TObject>().ToList();
}
public async Task<ICollection<TObject>> GetAllAsync()
{
return await Context.Set<TObject>().ToListAsync();
}
public TObject Get(int id)
{
return Context.Set<TObject>().Find(id);
}
}
连同这个;
public static class DA
{
public static DataAccess.Categories Categories => new DataAccess.Categories();
public static DataAccess.Tags Tags => new DataAccess.Tags();
public static DataAccess.Users Users => new DataAccess.Users();
}
public static class DA<T> where T : class
{
public static BaseService<T> Base => new BaseService<T>();
}
所以在我的业务层我可以做到这一点;
public class Categories
{
public Categories() { }
public ICollection<Database.Categories> GetAll()
{
return DA.Categories.GetAll().ToList();
}
public async Task<ICollection<Database.Categories>> GetAllAsync()
{
return await DA.Categories.GetAllAsync();
}
public Database.Categories Get(int id)
{
return DA.Categories.Get(id);
}
}
为清楚起见。我的 EF 创建了 classes/entities,比如 'Database.Categories' 和 'Database.Users',我将它们作为 'TObject' 传递给我的 BaseService,以获得拉取数据的标准方式来自我所有实体的数据库。
现在我的问题。我想以类似的方式创建一个通用的业务层。喜欢;
public class BusinessLogicBase<TModel>
{
public ICollection<TDBModel> GetAll()
{
return null;
}
public async Task<ICollection<TDBModel>> GetAllAsync()
{
return await DA.Categories.GetAllAsync();
}
public TDBModel Get(int id)
{
return DA.Categories.Get(id);
}
}
我希望能够使用类似 Database.Categories 的 TObject 调用 DA,但这必须是动态的,基于传递给 BusinessLogicBase 的类型。所以我想做这样的事情(这是行不通的);
private ???? DetermineDatabaseModel()
{
switch(typeof(TModell))
{
case Models.Categories:
return Database.Categories;
case Models.Users:
return Database.Users;
}
}
所以我可以做到;
public ICollection<TDBModel> GetAll()
{
var databaseModel = DetermineDatabaseModel()
return DA<databaseModel>().GetAll();
}
希望你能理解我的问题并能帮助我。
谢谢!
抱歉拖了这么久 post,对于所有 9gaggers,这里有一个土豆...不是开玩笑,这是认真的。
你有没有尝试过类似的东西:
public class BusinessLogicBase<TDBModel> where TDBModel : class {
public ICollection<TDBModel> GetAll() {
return DA<TDBModel>.Base.GetAll();
}
}
更新 1:
如果您先尝试在不使用泛型的情况下编写它,然后使用泛型将其转换为更通用的模式,也许会对您有所帮助。如果没有泛型,有些错误更容易解决。
方法 public ICollection<TDBModel> GetAll()
不能 return ICollection<TDBModel>
因为类型参数 TDBModel
未在 class 签名或方法签名中定义。如果你这样定义它更有意义:
public class BusinessLogicBase<TModel>
{
public ICollection<TModel> GetAll()
{
return null;
}
}
更新 2:
尝试 this simple console app 演示 dynamic
关键字并观察存储在变量 categories
和 users
.
更新 3:
基于 fiddle - 我已将 IBaseService<dynamic>
更改为 dynamic
:
public class BL<TModel>
{
// This is what i want to make dynamic.
// how do i create a return type that i can use in DA<>..
private Type testDetermineDatabaseModel()
{
switch(typeof(TModel).Name){
case "Categories":
return typeof(Database.Categories);
case "Users":
return typeof(Database.Users);
}
return null;
}
public ICollection<TModel> testGetAll()
{
var databaseModel = testDetermineDatabaseModel();
// return DA<databaseModel>().Base.GetAll();
return new List<TModel>();
}
// NEW
// I have constructed the following.
private dynamic baseService;
public dynamic DetermineDatabaseModel()
{
switch (typeof(TModel).Name)
{
case "Categories":
return new BaseService<Database.Categories>();
case "Users":
return new BaseService<Database.Users>();
default:
return null;
}
}
private IBaseService<TDbModel> GetBase<TDbModel>() where TDbModel : class
{
return new BaseService<TDbModel>();
}
public ICollection<TModel> GetAll()
{
ICollection<TModel> returnValue = new List<TModel>();
// This works!!!
foreach (var item in GetBase<Database.Categories>().GetAll())
{
returnValue.Add((TModel)(object)item);
}
baseService = DetermineDatabaseModel();
// This doesn't!!! It's the same thing!! :(
foreach (var item in baseService.GetAll())
{
returnValue.Add((TModel)(object)item);
}
return returnValue;
}
}
但请记住,这并不能解决您面临的问题。即 map 2 通用类型。