2016-09-06 47 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