我想在一个小项目中使用IRepository模式(由NHibernate支持,如果它很重要).域是一个简单的域,故意让我专注于理解IRepository模式.独行域类是Movie
,与性质Year
,Genre
和Title
.我的意图是"获取"其属性符合上述类型标准的电影.
惯例似乎是具有通用IRepository
接口,类似于以下内容:
public interface IRepository<T>
{
T Get(int id);
T[] GetAll();
void Add(T item);
void Update(T item);
void Delete(T item);
}
Run Code Online (Sandbox Code Playgroud)
有了基础实现:
public abstract class Repository<T> : IRepository<T>
{
public T Get(int id) { ... }
public T[] GetAll() { ... }
public void Add(T item) { ... }
public void Update(T item) { ... }
public void Delete(T item) { ... }
}
Run Code Online (Sandbox Code Playgroud)
然后有一个特定于域的界面:
public interface IMovieRepository
{
Movie[] …
Run Code Online (Sandbox Code Playgroud) 我一直试图想出一种方法来编写针对各种数据存储的通用存储库:
public interface IRepository
{
IQueryable<T> GetAll<T>();
void Save<T>(T item);
void Delete<T>(T item);
}
public class MemoryRepository : IRepository {...}
public class SqlRepository : IRepository {...}
Run Code Online (Sandbox Code Playgroud)
我想在每个中使用相同的POCO域类.我也在考虑类似的方法,每个域类都有自己的存储库:
public interface IRepository<T>
{
IQueryable<T> GetAll();
void Save(T item);
void Delete(T item);
}
public class MemoryCustomerRepository : IRepository {...}
public class SqlCustomerRepository : IRepository {...}
Run Code Online (Sandbox Code Playgroud)
我的问题:1)第一种方法是否可行?2)第二种方法是否有任何优势.
我有一个配置了CI帖子的构建,运行了一些测试.虽然测试成功运行,但构建显示警告:
:无法为StructuremapMvc生成存根:type已密封.:无法为IUnitOfWork生成填充程序:type是一个接口.:无法为Repository.IRepository`1生成填充程序:type是一个接口.
等等.
我正在使用通用存储库模式以及工作单元.我为我的MVC WebApi项目(利用StructureMap利用依赖注入)和包含我的存储库和UnitOfWork的数据项目添加了Fake Assemblies.我已经探究过这个错误并且似乎有点确信这可能是由于假装配的限制,但我需要绝对确定我没有做错任何事
我刚刚参与了Moq和单元测试,所以请原谅我,如果这看起来很明显(通过SO的快速搜索并没有向我展示这样的东西).
我有一个与以下提议成员的接口:
void AddFeed(Feed feed);
Run Code Online (Sandbox Code Playgroud)
我想为此功能编写单元测试.测试类有一个Moq Repository,声明如下:
static IFeedRepository MockFeedsRepository(params Feed[] feeds)
{
var mockFeedsRepository = new Moq.Mock<IFeedRepository>();
mockFeedsRepository.Expect(x => x.Feeds).Returns((feeds.AsQueryable));
return mockFeedsRepository.Object;
}
Run Code Online (Sandbox Code Playgroud)
如何修改模拟存储库声明以包含这个新的期望行为,或者我应该创建一个不同的Moq(以及如何完成).
我的假设是,在创建模拟之后,派生单元测试会更容易,但提示非常受欢迎.
非常感谢,
KevDog
我实际上正在寻找一些帮助来学习设计多个存储库的绳索,这些存储库将使用EF访问同一个数据库.我看过示例代码,其中每个存储库都有自己的私有DBContext,但我对此概念有困难.我对这个项目中的通用接口不感兴趣.
我想要一个Identity
基于(授权)的多个接口和其他作业特定的存储库,例如单个应用程序中的类别,项目等,其中继承的接口是可重用的,因此是多个DbContext
实例.
在SQL中,您有可以提交或回滚事务的事务,因此在EF中,多个repos会访问相同的(实时)数据吗?也许更好的问题是当我想要一个应用程序继承许多特定于作业的存储库时,我应该如何设计我的DAL.
什么jgauffin的意思是, "确保你的库是100%完全抽象化"
这是什么意思?
这是我想弄清楚的一个简单例子.这种做法合理吗?
public class OneRepo: IRepository, IDisposable
{
private DbContext context = new DbContext();
// Methods and whatnot...
}
Run Code Online (Sandbox Code Playgroud)
然后第二个存储库也需要OneRepo使用相同的数据库连接,但我认为它具有单独的内存单元吗?
public class AnotherRepo: IRepository, IDisposable
{
private DbContext context = new DbContext();
// Methods and whatnot...
}
Run Code Online (Sandbox Code Playgroud)
如果我的问题写得不好,我道歉.我实际上发帖比较新,我不确定自己是否清楚自己.我已经决定我不喜欢通用的repos,并且希望使用Role Interface模式基于授权和/或用户任务创建repos.任何帮助解释将不胜感激!
我正在考虑使用NHibernate实现IRepository模式,我有一个问题,我无法回答搜索网络.
假设我有3个存储库,PersonRepository,PersonAddressRepository和PersonAccountRepository.现在假设业务逻辑指示存在调用PersonRepository.Deactivate(),PersonAddressRepository.Deactivate()和PersonAccountRepository.Deactivate()的"Deactivate Person"进程.
我希望能够按照......的方式做点什么.
using (ITransaction transaction = session.BeginTransaction()) {
session.Update(Person);
session.Update(PersonAddress);
session.Update(PersonAccount);
}
Run Code Online (Sandbox Code Playgroud)
因此,如果任何更新失败,整个过程将在数据库中回滚.现在我对NHibernate的理解是,你只能为每个对象创建一个Session,所以...
var cfg = new Configuration();
cfg.Configure();
cfg.AddAssembly(typeof(Person).Assembly);
ISessionFactory sessionFactory = cfg.BuildSessionFactory();
using (ISession session = sessionFactory.OpenSession()) {
using (ITransaction transaction = session.BeginTransaction()) {
session.Save(Person);
}
Run Code Online (Sandbox Code Playgroud)
这是对的还是我弄错了?有关NHibernate的多表更新和事务的事务的最佳实践是什么?
提前致谢.
irepository ×6
c# ×4
unit-testing ×2
.net-3.5 ×1
dbcontext ×1
moq ×1
nhibernate ×1
structuremap ×1
transactions ×1