c# - 使用反射查找接口在装配类型中
问题描述
我不确定是否是尖括号导致了我的问题,但我无法在 Stack Overflow 的答案中找到答案。如果已经有一个,我欢迎你指出我正确的方向。
总而言之,我有一个接口,我无法通过反射找到它。让我们设置舞台:
接口
interface ICrew
{
string Name { get; set; }
}
interface IDataService<T>
{
IEnumerable<T> GetItems();
}
课程
class Crew : ICrew
{
public string Name { get; set; }
}
class CrewRepository : IDataService<ICrew>
{
DbContext _context { get; }
public CrewRepository(DbContext context)
{
_context = context;
}
public IEnumerable<ICrew> GetItems()
{
return _context.Crews;
}
}
class DbContext
{
public DbContext()
{
Crews = new List<Crew>();
}
public List<Crew> Crews;
}
代码
class Program
{
private static DbContext _context;
static void Main(string[] args)
{
_context = new DbContext();
//I want to find CrewRepository (which is type of IDataService<ICrew>)
var dataService = Get(typeof(ICrew));
}
private static object Get(Type T)
{
var types = typeof(CrewRepository).Assembly.GetTypes();
var test = types.Where(t => t.IsAssignableFrom(T)); //Finds ICrew
var test2 = types.Where(t => t.GetInterfaces().Contains(T)); //Finds Crew
var test3 = types.Where(t => t.GetInterfaces().Contains(typeof(IDataService<>))); //Finds nothing
var test4 = types.Where(t => t.IsAssignableFrom(typeof(IDataService<>))); //Finds interface IDataService
var test5 = types.Where(t => typeof(IDataService<>).IsAssignableFrom(t)); //Finds interface IDataService
var instance = types
.Where(t => t.IsAssignableFrom(T))
.FirstOrDefault();
if (instance != null)
{
return Activator.CreateInstance(instance, _context);
}
return default;
}
}
我不知道如何正确查询程序集类型以获取IDataService<T>
. 我的Get
方法直到运行时才知道它会被要求什么类型,并且只有在编译时知道类型时才能使用尖括号内的泛型。谁能帮我弄清楚我应该在这里做什么才能Get
通过使用反射返回我希望的正确类存储库?
解决方案
正如评论中提到的,必须使用该Type.MakeGenericType
方法在运行时创建所需的类型IDataService<"T">
。您的Get
方法可能如下所示:
private static object Get(Type t)
{
var types = typeof(CrewRepository).Assembly.GetTypes();
var runtimeType = typeof(IDataService<>).MakeGenericType(t);
var type = types.SingleOrDefault(x => x.GetInterfaces().Contains(runtimeType));
if (type != null)
{
return Activator.CreateInstance(type, _context);
}
return null;
}
推荐阅读
- mysql - 选择从 Y 行开始的 X 行
- hive - 将旧数据保留在分区配置单元表上
- django - Django modelformset_factory() 在视图中手动添加字段
- c# - 组合框 SelectedItem 未更改
- docker - 定期使用 LetsEncrypt 重新认证会产生负面影响吗?
- opensuse - 在 OpenSuse Leap 15.0 中配置 Oracle 监听器
- python - 找不到scrapy的永久修复
- java - 后缀评估器
- angular - 请求的资源 Asp.Net Web Api Owin 和 Angular 8 上不存在“Access-Control-Allow-Origin”标头
- javascript - Phaser 3 Arcade:将摄像机跟随玩家的 Y 设置为固定