我正在构建一个EntityFramework / WebApi后端 我想将我的WebApi与实体框架分离,并利用依赖注入,这样我就可以换掉"数据源"用于Web API。 我一直在研究工作单元和存储库模式。
我也想使用breezejs。
breezejs TempHire样本有很多帮助,所以我将以此为例来解答我的问题 -
https://github.com/Breeze/breeze.js.samples/tree/master/net/TempHire
在此示例中,在数据方面,我们有UnitOfWork类 -
public class UnitOfWork
{
private readonly EFContextProvider<TempHireDbContext> _contextProvider;
public UnitOfWork()
{
_contextProvider = new EFContextProvider<TempHireDbContext>();
StaffingResources = new Repository<StaffingResource>(_contextProvider.Context);
Addresses = new Repository<Address>(_contextProvider.Context);
// .. etc.
}
public IRepository<StaffingResource> StaffingResources { get; private set; }
public IRepository<Address> Addresses { get; private set; }
// .. etc.
public SaveResult Commit(JObject changeSet)
{
return _contextProvider.SaveChanges(changeSet);
}
}
然后在WebApi方面,它像这样使用它 -
[BreezeController]
[Authorize]
public class ResourceMgtController : ApiController
{
private readonly UnitOfWork _unitOfWork = new UnitOfWork();
[HttpPost]
public SaveResult SaveChanges(JObject saveBundle)
{
return _unitOfWork.Commit(saveBundle);
}
// ... etc.
}
我想重构这样的事情,以便我可以换掉后端。
public class UnitOfWork : IUnitOfWork
public class ResourceMgtController : ApiController
{
private readonly IUnitOfWork _unitOfWork;
public ResourceMgtController(IUnitOfWork unitOfWork) {
this._unitOfWOrk = unitOfWork; // Dependency Injected...
}
// ... etc.
}
我能够无法理解的是,我是如何让它变得通用的。 breeze客户端需要这样的方法 -
[HttpPost]
public SaveResult SaveChanges(JObject saveBundle)
{
return _unitOfWork.Commit(saveBundle);
}
我无法将其放入IUnitOfWork -
SaveResult SaveChanges(JObject saveBundle)
真的让它与微风分离,能够将后端换成另一个后端。我是否在错误的点上尝试抽象?我想如果我想在客户端上轻松,我需要在后端将它连接起来吗?
答案 0 :(得分:1)
您显然可以使用该方法定义界面:
public interface IUnitOfWork {
...
SaveResult SaveChanges(JObject saveBundle); // no problem
}
我怀疑你反对这样一个事实:SaveResult
和JObject
都是由图书馆定义的类(Breeze.ContextProvider
和Newtonsoft.Json.Linq
)你宁可不参考某处。
这些参考文献不会让我感到烦恼,因为我想引用System.Linq
来获取IQueryable
。事实上,SaveResult
(公共类Breeze.ContextProvider
)的测试双重很容易构建。这是它的定义(以及KeyMapping
的定义,它唯一的非原生依赖类型):
public class SaveResult
{
public List<object> Entities;
public List<KeyMapping> KeyMappings;
public List<object> Errors;
}
public class KeyMapping
{
public string EntityTypeName;
public object TempValue;
public object RealValue;
}
但是如果 Breeze 和 Newtonsoft.Json 引用对您有害并且您愿意放弃某些类型的安全性,那么您始终可以创建如下界面:
public interface IUnitOfWork {
...
object SaveChanges(object saveBundle); // no safety, no problem
}
然后在你的具体UnitOfWork
中添加一个合适的重载:
public object IUnitOfWork.SaveChanges(object saveBundle)
{
return SaveChanges((JObject) saveBundle);
}
public SaveResult SaveChanges(JObject saveBundle)
{
return _contextProvider.SaveChanges(saveBundle);
}
......鲍勃是你的叔叔。
是的,我确实尝试过(在DocCode中);对我来说很好。