【问题标题】:c# Generic Set<T> implementation to access objects by typec# Generic Set<T> 实现按类型访问对象
【发布时间】:2021-06-17 02:39:16
【问题描述】:

我正在开发一个 net Core WebApi 项目并实现一个工作单元模式来访问数据库中的记录。

考虑下面的类:

工作单元:

public class UnitOfWork : IUnitOfWork
{
    public IBooksRepository Books { get; }

    public ICatalogueRepository Catalogues { get; }
    
    ...
}

API 控制器:

public class StudentController: ApiController
{
    private IUnitOfWork _unitOfWork;
    public StudentController(IUnitOfWork UnitOfWork)
    {
        _unitOfWork = UnitOfWork;
    }

    public IActionResult Get()
    {
       var books =   _unitOfWork.Books.GetAll();
        return Ok(books);
    }
}

}

目前我正在使用上述方法从数据库中检索记录, 我想像这样访问存储库对象。

var books =   _unitOfWork.Set<IBooksRepository>.GetAll();

类似于 EntityFramework DBContext claas 中的Set&lt;T&gt; 方法,目的是使控制器类通用,并以通用的方式执行获取操作。

我怎样才能像Set&lt;T&gt; 方法那样从 UnitOfWork 类中找到存储库对象?

【问题讨论】:

  • 那会给你带来什么?
  • 根据您编写的原型,我看到的是对 IoC 容器的需求。 IoC 容器能够将接口与适当的实现相匹配。如果做不到这一点,你可以编写一个工厂方法来切换你所有的接口类型和news 到正确的类。
  • @RobertHarvey 通过这样做,我可以将控制器上的重复代码移动到基类中
  • "类似于 EntityFramework DBContext claas 中的 Set 方法" - TSet&lt;T&gt;() 的 EF DbContext 代表一个实体,你的不是.
  • 另外,您是否注意到DbContext 的功能看起来像Unit of Work 实现?那是因为它是一个。

标签: c# asp.net-core generics entity-framework-core dbcontext


【解决方案1】:

我同意罗伯特·哈维的观点。但是,如果您想这样做,一种方法是稍微重构您的代码,然后使用反射:

你可以稍微重构一下代码:

public class UnitOfWork : IUnitOfWork
{
    public IRepository<Book> Books { get; }

    public IRepository<Catalogue> Catalogues { get; }

    public IRepository<T> Set<T>()
    {
        var allProperties = this.GetType().GetProperties();

        var property = allProperties.SingleOrDefault(p => p.PropertyType == typeof(IRepository<T>) );
        return (IRepository<T>) property.GetValue(this);
    }
}

这只是一个入门/想法,您可以根据您的情况(优化、个人选项等)对其进行更多调整。

PS:你写了“类似于 EF 的Set&lt;T&gt;”,但是在你的代码示例中没有使用“实体类型”来获取存储库。您可以进一步简化我的示例以检查 T 并返回 T 而不是 IRepository&lt;T&gt;

public T Set<T>()
{
    var allProperties = this.GetType().GetProperties();

    var property = allProperties.SingleOrDefault(p => p.PropertyType == typeof(T) );
    return (T)property.GetValue(this);
}

但是,这似乎很愚蠢。如果您要走“通用存储库”路线,我认为应该有一个IRepository&lt;T&gt;

【讨论】:

  • 是的,你是对的。有一个 IRepository.
猜你喜欢
  • 2019-02-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-17
  • 1970-01-01
  • 2018-05-17
相关资源
最近更新 更多