在Breezejs中使用依赖注入

时间:2015-02-23 21:34:19

标签: entity-framework asp.net-web-api breeze

我正在构建一个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)

真的让它与微风分离,能够将后端换成另一个后端。我是否在错误的点上尝试抽象?我想如果我想在客户端上轻松,我需要在后端将它连接起来吗?

1 个答案:

答案 0 :(得分:1)

您显然可以使用该方法定义界面:

public interface IUnitOfWork {
    ...
    SaveResult SaveChanges(JObject saveBundle); // no problem
}

我怀疑你反对这样一个事实:SaveResultJObject都是由图书馆定义的类(Breeze.ContextProviderNewtonsoft.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中);对我来说很好。