使用泛型并在接口中实现可选字段或可选地实现接口?

时间:2016-09-06 12:27:42

标签: c# oop generics interface

我正在使用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;
    }
}

上述工作和更新从我的MVC视图Lookup1文件传递的所有Lookup2.cshtml模型字段。

但是,我的部分模型只有DateCreatedCreatedBy属性,我也想在通用控制器的Edit方法中更新这些属性。

类似这样的事情

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

然而,对于我这样做,我必须将这两个属性添加到接口IEntity,但这些属性仅属于某些模型,例如。Lookup2没有这两个属性。

我能想到的唯一解决方案是将nullable DateCreatedCreatedBy属性添加到我的所有模型类中,以便我可以将这些属性添加到IEntity接口并更新我的通用控制器中的那些字段。但是我不认为它是理想的,因为我没有兴趣为Lookup2

设置这些属性

我的问题:

  1. 是否可以在接口中使用条件属性或者可选地继承单独的条件接口?

  2. 或我的问题的另一个更简洁的解决方案?

1 个答案:

答案 0 :(得分: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);