簡體   English   中英

在EntityTypeConfiguration的構造函數中調用虛擬方法的風險如何 <T> ?

[英]How risky is calling a virtual method in the constructor of an EntityTypeConfiguration<T>?

我對所有實體類都有一個基類:

public class XTimeEntityTypeConfiguration<TEntity> : EntityTypeConfiguration<TEntity> where TEntity : XTimeEntity
{
  public XTimeEntityTypeConfiguration()
  {
      this.HasKey(t => t.Id);
      this.Property(t => t.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);        
      this.Ignore(t => t.IsActive);
  }
}

現在,我想使此默認行為可重寫,因為在某些實體類中需要邏輯來確定如何完成,例如,哪個屬性是關鍵。 我還想制作配置的其他部分,並且不能覆蓋構造函數,因此在考慮從構造函數調用虛擬方法時,充分意識到了這一點,同時還相當確信此基類的繼承深度幾乎總是一個,即每個實體一個派生的實現。 我提議的基類將是這樣的:

public abstract class XTimeEntityTypeConfiguration<TEntity> : EntityTypeConfiguration<TEntity> where TEntity : XTimeEntity
{
  protected XTimeEntityTypeConfiguration()
  {
    ConfigureProperties();
    ConfigureRelationships();
    ConfigureTableMapping();
    ConfigureKey();
    ConfigureColumnMappings();
  }

  protected virtual void ConfigureKey()
  {
    this.HasKey(t => t.Id);
    this.Property(t => t.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
  }

  protected virtual void ConfigureTableMapping()
  {
    var plurals = PluralizationService.CreateService(CultureInfo.CurrentCulture);
    this.ToTable(plurals.Pluralize(GetType().Name));
  }

  protected virtual void ConfigureColumnMappings() { }
  protected virtual void ConfigureProperties() { }
  protected virtual void ConfigureRelationships() { }
  protected virtual void ConfigureIgnores()
  {
    this.Ignore(t => t.IsActive);
  }
}

以及派生實例:

public class ActivityMap : XTimeEntityTypeConfiguration<Activity>
{
  public ActivityMap() : base() {}

  protected override void ConfigureProperties()
  {
    base.ConfigureProperties();
    this.Property(t => t.Name)
      .IsRequired()
      .HasMaxLength(30);
  }

  protected override void ConfigureColumnMappings()
  {
    base.ConfigureColumnMappings();
    this.Property(t => t.Id).HasColumnName("ACT_CODEID");
  }

  protected override void ConfigureTableMapping()
  {
    this.ToTable("ACTIVITY");
  }
}

也許您最好在這里使用Decorator Pattern 您可以將配置行為留給裝飾者,這樣就不會造成虛擬混亂:)

在這種情況下,請使用裝飾器基類,並從其派生以下內容:

public abstract class EntityConfigurationBehavior
{
    public abstract void Configure<TEntity>(EntityTypeConfiguration<TEntity> config);
}

public class DefaultConfigurationBehavior : EntityConfigurationBehavior
{
    public override void Configure<TEntity>(EntityTypeConfiguration<TEntity> config)
    {
        config.HasKey(t => t.Id);
        config.Property(t => t.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);        
        config.Ignore(t => t.IsActive);
    }
}

在配置類中,在配置中包含一個受保護的字段或屬性:

public abstract class XTimeEntityTypeConfiguration<TEntity> : EntityTypeConfiguration<TEntity> where TEntity : XTimeEntity
{
    // [...]

    protected EntityConfigurationBehavior ConfigurationBehavior { get; set; }

    // [...]
}

現在您可以像這樣調用它:

public class ActivityMap : XTimeEntityTypeConfiguration<Activity>
{
    public ActivityMap() : base() 
    {
        ConfigurationBehavior = new DefaultConfigurationBehavior(this);
    }
}

如果需要更多配置選項,則始終可以創建更多行為,或者如果過於混亂,請列出可以配置的行為。 我沒有使EntityConfigurationBehavior通用,因為您正在尋找一種配置所有通用屬性的方法。 您可以在ActivityMap本身中配置特定於Activity的屬性。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM