[英]How to determine that a class implements a specific interface with self-referencing, generic constraints?
我有一个DbContext
派生的 class 并希望获取其通用参数Entity
符合以下条件的所有DbSet<Entity>
属性的列表:
Entity
不得从 class 继承。Entity
必须实现接口IEntity
。Entity
必须实现接口IEntity<TEntity>
,其中TEntity
具有以下约束: where TEntity: class, IEntity, IEntity<TEntity>, new()
下面代码中的倒数第二行尝试这样做但失败了。 此外,我不知道如何在运行时表达约束检查。
属性DbSet<Employee>
应该通过检查,而DbSet<Department>
不应该。
namespace DomainBuilder
{
internal static class Program
{
private static void Main (string [] args)
{
var dbSetProperties = typeof (DomainBuilder.DomainBuilderContext)
.GetProperties (BindingFlags.Instance | BindingFlags.Public)
.Where (p => p.CanRead && p.CanWrite)
.Where (p => p.GetGetMethod (nonPublic: false) != null)
.Where (p => p.GetSetMethod (nonPublic: false) != null)
.Where (p => (p.PropertyType.Name.StartsWith (nameof (DbSet<DomainBuilder.IEntity>))))
.Where (p => (p.PropertyType.IsGenericType))
.Where (p => (p.PropertyType.GenericTypeArguments.Length == 1))
.ToList();
foreach (var dbSetProperty in dbSetProperties)
{
Console.WriteLine ($@"DbSet<{dbSetProperty.PropertyType.GenericTypeArguments [0].Name}>: {DomainBuilder.DomainBuilderContext.ImplementsIEntityGenericWithConstraints (dbSetProperty)}.");
}
}
}
public interface IEntity
{
public long Id { get; set; }
public DateTime DateTimeCreated { get; set; }
public DateTime DateTimeModified { get; set; }
}
public partial interface IEntity<TEntity>: IEntity
where TEntity : class, IEntity, IEntity<TEntity>, new()
{ }
public partial class Employee: IEntity<Employee>
{
public long Id { get; set; }
public DateTime DateTimeCreated { get; set; }
public DateTime DateTimeModified { get; set; }
public long? DepartmentId { get; set; }
public Department? Department { get; set; }
}
public partial class Department: IEntity
{
public long Id { get; set; }
public DateTime DateTimeCreated { get; set; }
public DateTime DateTimeModified { get; set; }
public string Name { get; set; } = "";
}
public partial class DomainBuilderContext: DbContext
{
public virtual DbSet<Employee>? Employees { get; set; }
public virtual DbSet<Department>? Departments { get; set; }
public static bool ImplementsIEntityGenericWithConstraints (PropertyInfo dbSetProperty)
{
var typeDbSet = dbSetProperty.PropertyType; // DbSet<Employee>.
var typeEntity = typeDbSet.GenericTypeArguments [0]; // Employee.
if (typeEntity.BaseType != typeof (object)) { return (false); }
var interfaces = typeEntity.GetInterfaces();
// Works fine.
var isIEntity = interfaces.Any (i => i == typeof (IEntity));
// How to ensure that [typeEntity] implements [IEntity<TEntity>]
// where TEntity: class, IEntity, IEntity<TEntity>, new().
var isIEntityGeneric = interfaces.Any (i => i == typeof (IEntity<>));
return (isIEntity && isIEntityGeneric);
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.