2016-09-06 76 views
2

我使用C# 6.NET 4.6.2使用泛型並在接口中實現可選字段或可選地實現接口?

我使用一個通用存儲庫和通用ASP.NET MVC Controller,因爲我有很多的查找表,並且不希望爲每個

這裏獨立的控制器和存儲庫是我的代碼簡化爲:

型號:

public interface IEntity 
{ 
    int Id { get; set; } 

} 

public class Lookup1:IEntity 
{ 

    public int Id { get; set; } 

    public string Lookup1Name { get; set; } 

    public string CreatedBy { get; set; } 

    public DateTime CreatedDate { get; set; } 
} 
public class Lookup2:IEntity 
{ 

    public int Id { get; set; } 

    public string Lookup2Name { get; set; } 

} 

存儲庫:

public interface IGenericRepository<TEntity> where TEntity : class, IEntity 
{ 
    void Update(TEntity obj); 
} 


public class GenericRepository<TEntity> : IGenericRepository<TEntity> where TEntity : class, IEntity 
{ 
    public void Update(TEntity obj) 
    { 
     table.Attach(obj); 
     _db.Entry(obj).State = EntityState.Modified; 
    } 
} 

通用控制器:

public abstract class GenericController<TModel> : Controller 
    where TModel : class,IEntity 
{ 

    private IGenericRepository<TModel> _repository; 

    [HttpPost] 
    public async Task<IActionResult> Edit(TModel model) 
    { 
     try 
     { 
      if (ModelState.IsValid) { 
       _repository.Update(model); 
       await _repository.Save(); 
      } 
     } 
     catch (Exception) 
     { 
      ModelState.AddModelError(string.Empty, "Unable to save changes."); 
     } 
     return View(model); 
    } 

控制器:

public class Lookup1Controller : GenericController<Lookup1> 
{ 
    private IGenericRepository<Lookup1> _repository; 

    public Lookup1Controller (IGenericRepository<Lookup1> repository) : base(repository) 
    { 
     _repository = repository; 
    } 
} 

public class Lookup2Controller : GenericController<Lookup2> 
{ 
    private IGenericRepository<Lookup2> _repository; 

    public Lookup2Controller (IGenericRepository<Lookup2> repository) : base(repository) 
    { 
     _repository = repository; 
    } 
} 

上述工作,並更新所有的Lookup1,是從我的MVC視圖.cshtml文件傳遞Lookup2模型字段。

但是,只有一些我的模型具有DateCreatedCreatedBy屬性,我想在我的通用控制器中的Edit方法中更新這些屬性。

像這樣

model.DateCreated = DateTime.Now; 
model.CreatedBy = _myService.Username; 

但是對我來說,做到這一點我有這兩個屬性添加到界面IEntity但這些屬性只屬於某些型號如Lookup2沒有這兩個屬性。

我能想到的唯一的解決辦法就是添加nullableDateCreatedCreatedBy屬性來我所有的模型類,所以我可以在我的通用控制器的屬性添加到IEntity接口和更新這些字段。但是我不認爲這是理想的,因爲我在爲Lookup2

設置這些屬性沒有興趣我的問題:

  1. 是否有可能具有條件性的接口或可選繼承一個單獨的條件接口?

  2. 或另一個整潔的解決方案,以我的問題?

+0

那麼'AttributeCollection'或'Dictionary - > PropertyName,Property'怎麼辦? –

+0

否則,您可以使用「抽象類」而不是「接口」。 –

+0

爲什麼你的實體實現接口IEntity。你似乎沒有在任何地方使用它?刪除它,一切都會正常工作 –

回答

2

使用另一個接口:

public interface ITraceableEntity : IEntity 
{ 
    string CreatedBy { get; set; } 
    DateTime CreatedDate { get; set; } 
} 

然後實現它所需的具體類:

public class Lookup1 : ITraceableEntity 
{ 
    public int Id { get; set; } 

    public string Lookup1Name { get; set; } 

    public string CreatedBy { get; set; } 

    public DateTime CreatedDate { get; set; } 
} 

在通用控制器如果該實例實現了這個接口,你可以檢查然後投它:

try 
{ 
    if (ModelState.IsValid) { 
     if (model is ITraceableEntity) 
     { 
      ((ITraceableEntity)model).CreatedBy = _myService.Username; // <--- 
      ((ITraceableEntity)model).CreatedDate = DateTime.Now;  // <--- 
     } 
     _repository.Update(model); 
     await _repository.Save(); 
    } 
} 
catch (Exception) 
{ 
    ModelState.AddModelError(string.Empty, "Unable to save changes."); 
} 
return View(model); 
+0

謝謝。你的代碼似乎沒有控制器必須實現'ITraceableEntity'接口工作,所以我不需要將它添加到行'在哪裏TModel:class,IEntity' – greay