asp.net-mvc - 如何避免存储库重复代码

标签 asp.net-mvc ninject repository-pattern

我已经成功设置了一个列出团队的简单 mvc 应用程序。我正在使用 Ninject 根据 Controller 注入(inject)适当的存储库(感谢堆栈溢出;)。一切看起来都不错,除了存储库代码看起来完全相同。我知道这是错误的。所以我的 TeamRepository 有两个类(目前)。

public class SwimTeamRepository : ITeamRepository<SwimTeam> 
{
    private readonly Table<SwimTeam> _teamTable;
    public SwimTeamRepository(string connectionString)
    {
        _teamTable = (new DataContext(connectionString).GetTable<SwimTeam>());
    }

    public IQueryable<SwimTeam> Team
    {
        get { return _teamTable; }
    }
}

public class SoccerTeamRepository : ITeamRepository<SoccerTeam>
{
    private readonly Table<SoccerTeam> _teamTable;
    public SoccerTeamRepository(string connectionString)
    {
        _teamTable = (new DataContext(connectionString).GetTable<SoccerTeam>());
    }

    public IQueryable<SoccerTeam> Team
    {
        get { return _teamTable; }
    }
}

除了类和表名称之外,它们看起来完全相同,所以显然我需要重构它。这里最好的方法是什么?辛格尔顿?工厂方法?

提前致谢!

最佳答案

您可以使用泛型:

public interface ITeamRepository<T>
{
}

public class TeamRepository<TTeam> : ITeamRepository<TTeam>
    where TTeam : Team
{
    private readonly Table<TTeam> _teamTable;
    public TeamRepository(string connectionString)
    {
        _teamTable = (new DataContext(connectionString).GetTable<TTeam>());
    }

    public IQueryable<TTeam> Team
    {
        get { return _teamTable; }
    }
}

public class Team
{
}

public class SwimTeam : Team
{
}

然后像这样使用它......

public void MyMethod()
{
    var repository = new TeamRepository<SwimTeam>();
}

...并像这样设置你的 IoC 容器 w/Ninject...

public class MyModule : NinjectModule
{
    public override void Load()
    {
        Bind<ITeamRepository<SwimTeam>>
            .To<TeamRepository<SwimTeam>>();
    }
}

public void MyMethod()
{    
    var repository = kernel.Get<ITeamRepository<SwimTeam>>();
}

如果您想获得真正的通用性并为所有映射类拥有一个存储库,您可以执行以下操作:

public interface IRepository
{
    IQueryable<T> Get<T>() where T : class, new();
}

public class Repository : IRepository, IDisposable
{
    private DataContext _dataContext;
    public Repository(string connectionString)
    {
        _dataContext = new DataContext(connectionString);
    }

    public IQueryable<T> Get<T>()
        where T : class, new()
    {
        return _dataContext.GetTable<T>().AsQueryable();
    }

    public void Dispose()
    {
        if (_dataContext != null)
        {
            _dataContext.Dispose();
            _dataContext = null;
        }
    }
}

...您可以像这样调用(设置 Ninject 容器后)...

using (var repository = kernel.Get<IRepository>())
{
    var swimTeam = repository.Get<SwimTeam>();
}

由于 Ninject 负责对象的生命周期管理,因此您不必将存储库包装在 using 语句中。事实上,如果您计划在存储库的生命周期内多次使用该存储库,那么您根本不想在那里使用 using 语句。当它的生命周期结束时,Ninject 会自动处理它。

这是一个good article作者:Rob Conery,介绍如何使用这种技术来减少使用不同 ORM 的摩擦。

由 keeg 编辑:

我认为

public class TeamRepository<TTeam> : ITeamRepository<TTeam> where TTeam : Team {}

应该是

public class TeamRepository<TTeam> : ITeamRepository<TTeam> where TTeam : class {}

如有错误,请指正。

关于asp.net-mvc - 如何避免存储库重复代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5969217/

相关文章:

c# - 当作为 ActionResult 返回时,MemoryStream 是否会自动处理掉?

jquery - 使用 ASP.NET MVC 和 JQuery 表单插件/文件上传检测 IsAjaxRequest()

c# - 正则表达式问题(在asp.net MVC5中)

c# - 在 MVC 4 中保持和执行时间

c# - 如何使用 Quartz.net 和 log4net 配置 ninject

ioc-container - IoC/DI - 在只有内部方法的内部类中实现

c# - Ninject - 管理泛型类型的不一致性?

c# - 在连接 LINQ 中使用多个条件。我,我和

php - mock 不从存储库(接口(interface))调用方法

c#-4.0 - 使用 Moq 模拟存储库时出现问题