我已经成功设置了一个列出团队的简单 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/