我已经成功设置了一个列出团队的简单mvc应用程序。我正在使用Ninject根据控制器注入适当的存储库(由于堆栈溢出;)。除了存储库代码看起来完全相同外,所有看起来都很好。我知道这是错的。所以我的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; }
}
}
除了Class和Table名称外,它们看起来完全一样,所以显然我需要重新考虑这一点。这里最好的方法是什么?辛格尔顿?工厂方法?
提前致谢!
答案 0 :(得分:4)
您可以使用泛型:
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>>();
}
如果你想获得REAL泛型并且为所有映射类都有一个存储库,你可以这样做:
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会在生命周期结束时自动处理它。
这是Rob Conery使用这种技术减少使用不同ORM的摩擦的good article。
编辑keeg:
我想
public class TeamRepository<TTeam> : ITeamRepository<TTeam> where TTeam : Team {}
应该是
public class TeamRepository<TTeam> : ITeamRepository<TTeam> where TTeam : class {}
如果我错了,请纠正。
答案 1 :(得分:1)
这是你想要的吗?
public class TeamRepository : ITeamRepository<T>
{
private readonly Table<T> _teamTable;
public TeamRepository(string connectionString)
{
_teamTable = (new DataContext(connectionString).GetTable<T>());
}
public IQueryable<T> Team
{
get { return _teamTable; }
}
}