获取通用接口的所有实现类型

2024-03-21

我试图使用以下代码获取 IEntityModelBuilder 的所有实现,但它返回一个空集合。

public class EntityFrameworkDbContext : DbContext
{
    //constructor(s) and entities DbSets...

    private static IEnumerable<IEntityModelBuilder<IEntity>> _entitymodelBuilders;
    internal IEnumerable<IEntityModelBuilder<IEntity>> EntityModelBuilders
    {
        get
        {
            if (_entitymodelBuilders == null)
            {
                var type = typeof(IEntityModelBuilder<IEntity>);

                _entitymodelBuilders = Assembly.GetAssembly(type).GetTypes()
                    .Where(t => type.IsAssignableFrom(t) && t.IsClass)
                    .Select(t => (IEntityModelBuilder<IEntity>)Activator.CreateInstance(t, new object[0]));
            }

            return _entitymodelBuilders;
        }
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        foreach (var builder in EntityModelBuilders)
            builder.Build(modelBuilder);

        base.OnModelCreating(modelBuilder);
    }
}

internal interface IEntityModelBuilder<TEntity> where TEntity : IEntity
{
    void Build(DbModelBuilder modelBuilder);
}

//sample implementation
internal class UserModelBuilder : IEntityModelBuilder<User>
{
    public void Build(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<User>()
            .ToTable("users")
            .HasKey(e => e.Id);

        modelBuilder.Entity<User>()
            .Property(e => e.Id)
            .HasColumnName("id");

        modelBuilder.Entity<User>()
            .Property(e => e.Email)
            .HasColumnName("email");

        //and so on...
    }
}

如果我改变类型

var type = typeof(IEntityModelBuilder<User>);

类型获取代码运行良好并返回预期的 UserModelBuilder。我怎样才能用泛型做到这一点?


尽管 Slava 的解决方案有效,但总的来说,它并不是完全安全的,因为Contains. It is某些其他接口/类型可能包含您正在搜索的接口的名称。在这种情况下,假设您有另一个名为IEntityModelBuilderHelper.

此外,只需很少的努力,您就可以将此代码概括为更强大的功能。考虑以下两种方法:

public static IEnumerable<Type> GetAllTypes(Type genericType)
{
    if (!genericType.IsGenericTypeDefinition)
        throw new ArgumentException("Specified type must be a generic type definition.", nameof(genericType));

    return Assembly.GetExecutingAssembly()
                   .GetTypes()
                   .Where(t => t.GetInterfaces()
                                .Any(i => i.IsGenericType &&
                                     i.GetGenericTypeDefinition().Equals(genericType)));
}

And,

public static IEnumerable<Type> GetAllTypes(Type genericType, params Type[] genericParameterTypes)
{
    if (!genericType.IsGenericTypeDefinition)
        throw new ArgumentException("Specified type must be a generic type definition.", nameof(genericType));

    return Assembly.GetExecutingAssembly()
                   .GetTypes()
                   .Where(t => t.GetInterfaces()
                                .Any(i => i.IsGenericType &&
                                          i.GetGenericTypeDefinition().Equals(genericType) &&
                                          i.GetGenericArguments().Count() == genericParameterTypes.Length &&
                                          i.GetGenericArguments().Zip(genericParameterTypes, 
                                                                      (f, s) => s.IsAssignableFrom(f))
                                                                 .All(z => z)));
}

前者将为您提供实现所提供的泛型类型的所有类型定义, 那是typeof(MyGenericType<>),对泛型类型参数没有任何限制。后者将执行相同的操作,但具有提供的类型约束。

考虑以下类型:

public interface IFoo<T> { }
public interface IEntity { }
public class A : IEntity { }

public class Foo : IFoo<IEntity> { }
public class FooA : IFoo<A> { }
public class FooS : IFoo<string> { }

var types = GetAllTypes(typeof(IFoo<>));将返回 3 种类型:{ Foo, FooA, FooS } while var types = GetAllTypes(typeof(IFoo<>), typeof(IEntity));将仅返回两种类型:{ Foo, FooA }.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

获取通用接口的所有实现类型 的相关文章

  • 关于逻辑/算法的想法以及如何防止线程写入 Sql Server 中的竞争

    我有以下逻辑 public void InQueueTable DataTable Table int incomingRows Table Rows Count if incomingRows gt RowsThreshold async
  • 为什么 C 程序使用 Scanf 给出奇怪的输出?

    我目前正在学习 C 编程 并且遇到了这个奇怪的输出 Program will try functionalities of the scanf function include
  • 无法继承形状

    为什么我不能使用继承 a 的类Shapes class http msdn microsoft com en us library ms604615 28v vs 90 29 我需要延长Rectangle具有一些方法的类 但我想以与使用相同
  • 如何在 C# 中将 Json 转换为对象

    我想将 Json 转换为 C 中的对象 这里的 Json 是 值 e920ce0f e3f5 4c6f 8e3d d2fbc51990e4 如何使用 Object 问题看似愚蠢 但其实并不那么愚蠢 我没有简单的 Json 我有 IEnume
  • C# 中一次性对象克隆会导致内存泄漏吗?

    检查这个代码 class someclass IDisposable private Bitmap imageObject public void ImageCrop int X int Y int W int H imageObject
  • Android NDK 代码中的 SIGILL

    我在市场上有一个 NDK 应用程序 并获得了有关以下内容的本机崩溃报告 SIGILL信号 我使用 Google Breakpad 生成本机崩溃报告 以下是详细信息 我的应用程序是为armeabi v7a with霓虹灯支持 它在 NVIDI
  • 为什么这个 makefile 在“make clean”上执行目标

    这是我当前的 makefile CXX g CXXFLAGS Wall O3 LDFLAGS TARGET testcpp SRCS main cpp object cpp foo cpp OBJS SRCS cpp o DEPS SRCS
  • Libev,如何将参数传递给相关回调

    我陷入了 libev 中争论的境地 通常 libev 在类似的函数中接收包 接收回调 没关系 但是实际操作中 我们需要派遣一个亲戚 写回调 根据收到的包裹处理具体工作 例如 S RECV MSG pstRecvMsg S RECV MSG
  • C# 获取数据表中所有重复行的计数

    我通过运行存储过程来填充数据集 并且从数据集中填充数据表 DataSet RawDataSet DataAccessHelper RunProcedure storedprocedureName this will just return
  • wordexp 失败时我们需要调用 wordfree 吗?

    wordexp 失败时我们需要调用 wordfree 吗 在某些情况下 调用 wordfree 似乎会出现段错误 例如 当 wordfree 返回字符串为 foo bar 的错误代码时 这在手册页中并不清楚 我已经看到在某些错误情况下使用了
  • 如何在 Javascript 中连接 C# ActiveX 事件处理程序

    我尝试使用几个代码片段将 ActiveX 对象与 Javascript 事件处理程序挂钩 我无法确定为什么事件处理程序没有被调用 带有项目的 Github 存储库 https github com JesseKPhillips Csharp
  • Unity c# 四元数:将 y 轴与 z 轴交换

    我需要旋转一个对象以相对于现实世界进行精确旋转 因此调用Input gyro attitude返回表示设备位置的四元数 另一方面 这迫使我根据这个四元数作为默认旋转来计算每个旋转 将某些对象设置为朝上的简单方法如下 Vector3 up I
  • MySQL 连接器 C++ 64 位在 Visual Studio 2012 中从源代码构建

    我正在尝试建立mySQL 连接器 C 从源头在视觉工作室2012为了64 bit建筑学 我知道这取决于一些boost头文件和C 连接器 跑步CMake生成一个项目文件 但该项目文件无法编译 因为有一大堆非常令人困惑的错误 这些错误可能与包含
  • SQLAPI++ 的免费替代品? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 是否有任何免费 也许是开源 的替代品SQLAPI http www sqlapi com 这个库看起来
  • 以编程方式创建 Blob 存储容器

    我有一个要求 即在创建公司时 在我的 storageaccount 中创建关联的 blob 存储容器 并将容器名称设置为传入的字符串变量 我已尝试以下操作 public void AddCompanyStorage string subDo
  • Xamarin Forms Binding - 访问父属性

    我无法访问页面的 ViewModel 属性以便将其绑定到 IsVisible 属性 如果我不设置 BindingContext 我只能绑定它 有没有办法可以在设置 BindingContext 的同时访问页面的 viewmodel root
  • C:设置变量范围内所有位的最有效方法

    让我们来int举个例子 int SetBitWithinRange const unsigned from const unsigned to To be implemented SetBitWithinRange应该返回一个int其中所有
  • 如何编写一个接受 int 或 float 的 C 函数?

    我想用 C 语言创建一个扩展 Python 的函数 该函数可以接受 float 或 int 类型的输入 所以基本上 我想要f 5 and f 5 5 成为可接受的输入 我认为我不能使用if PyArg ParseTuple args i v
  • 如果找不到指定的图像文件,显示默认图像的最佳方式?

    我有一个普通的电子商务应用程序 我将 ITEM IMAGE NAME 存储在数据库中 有时经理会拼错图像名称 为了避免 丢失图像 IE 中的红色 X 每次显示产品列表时 我都会检查服务器中是否有与该产品相关的图像 如果该文件不存在 我会将其
  • 嵌入式linux编写AT命令

    我在向 GSM 模块写入 AT 命令时遇到问题 当我使用 minicom b 115200 D dev ttySP0 term vt100 时它工作完美 但我不知道如何在 C 代码中做同样的事情 我没有收到任何错误 但模块对命令没有反应 有

随机推荐

  • 如何在spark-jdbc应用程序中给出表名以读取RDBMS数据库上的数据?

    我正在尝试使用 Spark 读取 greenplum 数据库上存在的表 如下所示 val execQuery s select allColumns 0 as flagCol from schema table where period y
  • 从终端在 xcode PhoneGap 项目中定义方案

    我正在编写一个脚本来存档phonegap 项目的iOS 部分 该脚本会擦除项目所在的目录 然后使用源代码管理中的最新代码重新填充该目录 然后我跑 phonegap local build ios为了构建该项目 然而 为了归档该项目 我需要定
  • 在 Node.js 中生成并终止进程

    我正在尝试在 javascript 中生成一个进程 并在一段时间后终止它 出于测试目的 最后 该进程将是一个无限循环 我需要在指定时间使用不同的参数重新启动 因此我认为生成进程并终止它是执行此操作的最佳方法 我的测试代码是 var spaw
  • 用户默认值/KeyedArchiver 挫败感

    我正在开发一个作业应用程序 该应用程序为每个作业使用自定义作业对象 我试图在 standardUserDefaults 中存储 NSMutableArray 通过 initWithArray 转换为 NSArray 但在保存和重新加载数组时
  • 如何将 subversion 树从 v1.7 降级到 v1.6?

    有没有办法将 subversion 工作副本从版本 1 7 降级到版本 1 6x 版本 1 7 使用单个 svn 根文件夹和 sqlite 来存储元数据 因此 tigris org 中的转换 python 脚本不起作用 您是否知道一种不涉及
  • 如何关闭 Android 应用程序?

    如何关闭 Android 应用程序 我没有找到应用程序对象的关闭命令 我想在出现某些严重错误时关闭并重新启动 如果存在某种 严重错误 那么您应该在代码中处理它 而不是尝试重新启动应用程序 您无法关闭 Android 中的应用程序 但是一旦所
  • 如何防止光标在退出 Vim 插入模式时向后移动一个字符?

    是否可以取消上述行为 额外学分的任务 想办法强制 Vim 在退出插入模式后立即刷新光标位置 虽然我不建议更改默认的光标机制 实现相关行为的一种方法是使用以下内容 插入模式映射 inoremap
  • 绕过表单身份验证自动重定向到登录,如何?

    我正在编写一个使用 asp net mvc 部署到 iis6 的应用程序 我正在使用表单身份验证 通常 当用户尝试在未经适当授权的情况下访问资源时 我希望他们被重定向到登录页面 FormsAuth 对我来说这件事很简单 问题 现在我有一个由
  • 使用 pyqtgraph 和 LiDAR 快速实时绘制点

    我想创建一个实时的点图 GUI 我正在使用 Scanse Sweep LiDAR 每次扫描该 LiDAR 工作频率为 1 10Hz 时 我都会收到大约 1000 个描述 LiDAR 周围环境的点 x y 这是一个 2D 激光雷达 我到处寻找
  • mysql 5.6 外键约束错误; 5.5中没有出现

    涉及表 phppos permissions actions mysql gt show create table phppos permissions actions
  • Sublime Text 3 构建系统:保持控制台运行

    我在 Sublime Text 3 中设置了一个构建系统来运行 Matlab 文件 这真的很好用 cmd usr local MATLAB R2013b bin matlab nosplash nodesktop nojvm r run f
  • 获取 CN1 上没有时间的当前日期

    我在没有时间的情况下获取日期时遇到很大问题 我想将时间设置为 00 00 以便我可以检查日期差异 到目前为止我尝试的步骤 SimpleDateFormat dateFormat new SimpleDateFormat dd MM yyyy
  • 如何设置SMO ScriptingOptions以保证表的精确副本?

    我正在尝试做的事情 使用 C 创建 SQL 脚本来创建exact现有表的副本 我的问题 您将如何定义 scriptingOptions 中的选项以确保生成的脚本将创建 100 精确的表副本 有 78 个选项 目前尚不清楚如何执行此操作 最初
  • 将 ODP.NET 12 (VS2012) 连接到 Oracle 数据库 11 时出现 ORA 03134 错误

    当尝试使用 ODP NET 12 从 VS2012 连接到 Oracle 9 2 时 我收到以下消息 ORA 03134 不再支持与此服务器版本的连接 我已经安装了 ODP NET 11 但遇到了同样的错误 尽管与 Toad 的连接正常 有
  • 查询返回没有记录显示在我的网页上

    我有一个网站 我正在其中运行以下代码
  • 如何在node.js中处理stdout

    我试图自动化每次在服务器上测试应用程序和网站时所经历的过程 我目前正在nodejitsu上运行 当我测试了某些东西并且它可以在我的本地计算机上运行时 我要做的下一件事是 打开我的 package json 文件 删除域字段并将名称和子域更改
  • Spring 4 二进制文件下载

    我已经有一段时间没有下载spring了 我正在研究 gradle 但似乎还没有掌握它的窍门 所以我想使用 java Spring 4 和 ant 创建一个新的 spring 框架项目 我似乎找不到下载 Spring 4 二进制文件的地方 他
  • java.lang.ClassNotFoundException:com.mysql.jdbc.Driver。 [复制]

    这个问题在这里已经有答案了 我正在使用 Java Eclipse 连接 MySQL 数据库 但遇到以下错误 错误信息 无法连接到数据库java lang ClassNotFoundException com mysql jdbc Drive
  • 如何使用 JSON 数据递归填充 TreeView

    我有一个winforms树视图 我可以自动读取数据 一个等于key的节点 以及一个等于value的节点 但是当读取对象类型时 它里面的值不会是对象的子对象节点 对象的键 也许我无法很好地解释 这是屏幕截图和我的方法 Layer0 需要位于纹
  • 获取通用接口的所有实现类型

    我试图使用以下代码获取 IEntityModelBuilder 的所有实现 但它返回一个空集合 public class EntityFrameworkDbContext DbContext constructor s and entiti