【问题标题】:Create a new type based on other type, just changing the name在其他类型的基础上创建一个新类型,只是改变名称
【发布时间】:2021-09-17 08:40:14
【问题描述】:

我有一个类型,想创建一个新类型,基于这个类型,只是想更改名称。

例子:

var oldType = someObject.GetType();

var type = CreateNewType(oldType, "newType");

请允许我解释一下:

我正在动态创建多个数据库(通过在 EF Core 上下文中添加模型)。这很有效,但仅在第一次尝试时有效,但在第二次尝试时无效,因为他将以前的表保留为单例上下文(附加到我所看到的类型)。

【问题讨论】:

  • 说真的……为什么? “基于”是什么意思?:源自?有不同名称的副本?什么?
  • 我有一个动态的 EF Core 上下文。 DI 显然有一个单例数据库创建,它只在第一次尝试时有效。如果您创建具有动态行为的新数据库迁移,他将尝试添加之前添加的表。
  • 我觉得这里没有足够的信息。我建议调查在 DI 中不使用单例(这样您可以启动不同的数据库上下文),或者使用不同的模式(iirc,默认值为 [dbo.],但您可以更改它)。
  • 理论上它们是不同的上下文。模型不同,但它们是在运行时添加到同一类的。那就是问题所在。只需一种新类型就可以解决问题(见鬼)。

标签: c# .net .net-core


【解决方案1】:

在运行时构建新类型的唯一方法是使用一些重载反射来动态创建 IL 代码:

话虽如此,除非您有非常具体的需求,否则这听起来像XY problem。我建议您创建一个新问题来描述您在使用 EF 核心时遇到的具体问题(包括 minimal reproducible example),并让 EF 专家提出替代解决方案。

【讨论】:

  • 是的,这是一个 XY 问题。但不管怎样,我这里已经有了那个代码。我只需要找到一种方法来创建一种从具有逻辑的类型扩展的类型。这可以解决问题,但仍然肯定是hacky。最终,将有成千上万的新类型,我不知道从长远来看这是否是一个问题
【解决方案2】:

只是在这里回答问题本身,即使不是最好的解决方案:

可以从这里改编:

Creating dynamic type from TypeBuilder with a base class and additional fields generates an exception

代码:

public class ClassBuilder
{
    readonly AssemblyName _assemblyName;

    public ClassBuilder(string className)
    {
        _assemblyName = new AssemblyName(className);
    }

    public Type CopyType(Type type, string name)
    {
        var assemblyBuilder =
            AssemblyBuilder.DefineDynamicAssembly(new AssemblyName(name), AssemblyBuilderAccess.Run);
        ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("MainModule");

        TypeBuilder typeBuilder = moduleBuilder.DefineType(_assemblyName.FullName
            , TypeAttributes.Public |
              TypeAttributes.Class |
              TypeAttributes.AutoClass |
              TypeAttributes.AnsiClass |
              TypeAttributes.BeforeFieldInit |
              TypeAttributes.AutoLayout
            , type);

        typeBuilder.DefineDefaultConstructor(MethodAttributes.Public | MethodAttributes.SpecialName |
                                             MethodAttributes.RTSpecialName);

        return typeBuilder.CreateType();
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-15
    • 1970-01-01
    • 2020-11-26
    • 1970-01-01
    • 1970-01-01
    • 2018-05-22
    • 2018-04-22
    相关资源
    最近更新 更多