是否可以将类型添加到c#中的现有模块中

本文关键字:模块 类型 添加 是否 | 更新日期: 2023-09-27 18:29:59

在这种情况下,我需要向应用程序动态添加类型。基本上,我们希望使用EF6,但仍然对数据库运行完全动态的查询,并返回键/值对的字典。(遗留代码,不要问)

我可以通过调用context.Database.SqlQuery并将我动态创建的动态加载类型传递给它来实现这一点。

我正在使用我在网上找到的这种方法。

private static TypeBuilder CreateTypeBuilder(
    string assemblyName, string moduleName, string typeName)
{
    TypeBuilder typeBuilder = AppDomain.CurrentDomain
        .DefineDynamicAssembly(new AssemblyName(assemblyName), AssemblyBuilderAccess.Run)
        .DefineDynamicModule(moduleName)
        .DefineType(typeName, TypeAttributes.Public);
    typeBuilder.DefineDefaultConstructor(MethodAttributes.Public);
    return typeBuilder;
}

这很好,但每次我添加一个新类型(可能经常)时,它都会加载一个新的动态部件。这可能导致数百个程序集只使用一次。

我可以使用以下语句来拉下动态组件:

var loadedAssembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(ex => ex.GetName().Name == assemblyName);

我还可以使用以下方法获得动态模块:

var loadedModule = loadedAssembly.GetModules().FirstOrDefault(ex => ex.ScopeName == moduleName);

但就我所知,我无法添加任何超过这一点的类型。

我是不是找错树了?

是否可以将类型添加到c#中的现有模块中

关键部分是这一行:

.DefineDynamicAssembly(new AssemblyName(assemblyName), AssemblyBuilderAccess.Run)
.DefineDynamicModule(moduleName)

该方法返回一个动态程序集和模块的实例。不是每次需要新类型时都调用DefineDynamicAssemblyDefineDynamicModule,而是创建一次动态程序集和模块,然后针对所需的每个类型在模块上调用DefineType。也许是这样的:

internal static class DyanamicTypeBuilder
{
    private static readonly AssemblyBuilder _assembly;
    private static readonly ModuleBuilder _module;
    private static readonly object _syncBlk = new object();
    static DyanamicTypeBuilder()
    {
        _assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("MyDyanmicAssembly"), AssemblyBuilderAccess.Run);
        _module = _assembly.DefineDynamicModule("MyDynamicModule");
    }
    private static TypeBuilder CreateTypeBuilder(string typeName)
    {
        lock (_syncBlk)
        {
            var typeBuilder = _module.DefineType(typeName, TypeAttributes.Public);
            typeBuilder.DefineDefaultConstructor(MethodAttributes.Public);
            return typeBuilder;
        }
    }
}