带DRY的C#动态类

时间:2018-01-17 02:39:12

标签: c# dynamic

因此,我正在使用EF和C#创建一个REST API,并最终拥有许多具有完全相同结构的类。它们之间唯一不同的是命名和变量。我很难理解我需要寻找什么来动态创建一个类,具体取决于调用哪个API端点。

以下是两个示例类:

public class SiteExtendedAttributesBooleanContext : DbContext<ExtendedAttributeBoolean>
{
    public SiteExtendedAttributesBooleanContext(string nameOrConnectionString, string schemaName)
        : base(nameOrConnectionString, schemaName)
    {
        this.Configuration.ProxyCreationEnabled = true;
        this.Configuration.LazyLoadingEnabled = false;
    }

    /// <summary>
    /// this is used for unit testing only b/c a parameterless constructor is needed to create a proxy
    /// </summary>
    protected SiteExtendedAttributesBooleanContext() : base("A fake connection string", "FAKESCHEMA")
    {
        // ReSharper disable once VirtualMemberCallInConstructor
        OnModelCreating(new DbModelBuilder());
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder.Configurations.Add(new ExtendedAttributesBooleanMap("SITE_EXT_BOOLEAN"));

        var conv = new AttributeToTableAnnotationConvention<TenantAwareAttribute, string>(
            TenantAwareAttribute.TenantAnnotation, (type, attributes) => attributes.Single().ColumnName);

        modelBuilder.Conventions.Add(conv);
    }
}

public class AssetExtendedAttributesBooleanContext : DbContext<ExtendedAttributeBoolean>
{
    public AssetExtendedAttributesBooleanContext(string nameOrConnectionString, string schemaName) 
        : base(nameOrConnectionString, schemaName)
    {
        this.Configuration.ProxyCreationEnabled = true;
        this.Configuration.LazyLoadingEnabled = false;
    }

    /// <summary>
    /// this is used for unit testing only b/c a parameterless constructor is needed to create a proxy
    /// </summary>
    protected AssetExtendedAttributesBooleanContext() : base("A fake connection string", "FAKESCHEMA")
    {
        // ReSharper disable once VirtualMemberCallInConstructor
        OnModelCreating(new DbModelBuilder());
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder.Configurations.Add(new ExtendedAttributesBooleanMap("ASSETS_EXT_BOOLEAN"));

        var conv = new AttributeToTableAnnotationConvention<TenantAwareAttribute, string>(
            TenantAwareAttribute.TenantAnnotation, (type, attributes) => attributes.Single().ColumnName);

        modelBuilder.Conventions.Add(conv);
    }
}

是否可以使用单个类并使用不同的命名和字符串中的不同值创建另一个类?我一直在谷歌搜索动态类型,ExpandoObject,TypeBuilder等等,但我不确定符合我的需求。

我已经知道所有类的结构,只是不想为我正在创建的每个不同的API端点设置10个类。

2 个答案:

答案 0 :(得分:0)

只需创建一个这样的枚举: enum ContextType { Site, Asset, OtherOne }

并向构造函数添加一个参数: public ExtendedAttributesBooleanContext(string nameOrConnectionString, string schemaName, ContextType context)

因此,您可以在实例化时传递ContextType.SiteContextType.Asset或另一个传递。现在,您可以根据构造函数中传递的内容确定字符串。

创建私有字符串字段typeString。在构造函数中,指定&#34; ASSETS&#34;或&#34; SITE&#34;基于传递的参数(typeString = context == ContextType.Site ? "SITE" : "ASSETS";),然后在OnModelCreating中,只需将字符串文字替换为typeString

答案 1 :(得分:0)

为我的应用程序的另一个方面弄清楚我的部分问题。我基本上可以做到这一点:

private Dictionary<string, dynamic> DynamicContexts => new Dictionary<string, dynamic>
    {
        {"DOC_DOCUMENTS_EXT_BOOLEAN", DocumentExtendedAttributesBooleanContext},
        {"DOC_DOCUMENTS_EXT_STRING", DocumentExtendedAttributesTextContext}
        {"AST_ASSETS_EXT_BOOLEAN", AssetExtendedAttributesBooleanContext},
        {"AST_ASSETS_EXT_STRING", AssetExtendedAttributesTextContext}
    }

为了获得正确的背景,我称之为:

DynamicContexts[validEaTable]

我仍在努力寻找我在这里发布的原始课程的解决方案。可能需要做某种抽象类或继承。还不确定。