首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >工作单元属于w/ EF4、IoC (统一)和Repository?

工作单元属于w/ EF4、IoC (统一)和Repository?
EN

Stack Overflow用户
提问于 2011-02-17 07:41:33
回答 2查看 4K关注 0票数 7

我看到了几个与此有关的问题,但我仍然找不到我想要的答案,所以我正在张贴我的问题。如果另一个问题有答案(我只是没看到),请给我指点。

我试图找出我的UnitOfWork属于哪里--特别是创建--当使用EF4和模式时。

基本上,我有一个用于实现业务逻辑的服务。这个服务构造函数接受存储库,因此服务被注入到我的存储库中。然后,服务使用注入的存储库对数据存储执行操作--但我需要将这些操作封装在一个工作单元中。

然而,我的工作单元需要注入EF4上下文(或者,在我的例子中,是上下文-IObjectContext的接口)。我不知道应该在哪里创建和注入UoW /上下文。

以下是我能想到的可能的选择,其中没有一个看起来是理想的:

  • 在服务构造函数中包含UoW,从而将服务注入w/工作单元,然后注入w/ my EF4上下文。但这似乎是错误的,因为我不希望在存储库的每个实例上创建我的UoW,
  • 使用container.Resolve进行按需创建,以获取UoW的实例,并注入EF4上下文。这似乎过多地需要不断地访问IoC容器,而不是已经可以访问UoW。
  • 将上下文直接注入到服务中,允许我创建一个UoW(上下文)。这似乎很糟糕,因为我现在已经向服务公开了上下文,并且应该将其隔离到存储库中。

所以我的问题是,这些方法中的一种是可以接受的,还是我没有想到的另一种方法?

提前谢谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-02-17 09:00:43

可能有几种方法来使用它,所以我将描述一种我认为有用的方法。

定义UoW的地方是应用程序逻辑--调用业务层(业务服务)的逻辑。原因是UoW应该表示逻辑业务事务--应用程序逻辑(或远程调用情况下的服务外观)定义了什么是逻辑事务。因此,例如,在MVC中,您可以使用体系结构,其中每个控制器动作表示单个UoW:

代码语言:javascript
复制
public class MyController : Controller
{
  public MyController(IFirstService firstService, ISecondService secondService,
    IUnitOfWork unitOfWork)
  { ... }

  [HttpPost]
  public ActionResult SomeAction(Model data)
  {
    _firstService.SomeProcessing(data);
    _secondService.SomeProcessing(data);
    _unitOfWork.SaveChanges();
    return RedirectToAction(...);
  }
}

在本例中,我的控制器依赖于两个业务服务,并且操作都调用它们- UoW,然后保存由两个服务执行的更改。这就是为什么我认为UoW应该在控制器中可用的原因,因为如果您的应用层无法访问UoW,您就无法从几个服务调用中组合(重用)您的逻辑(因为每个调用都可能调用自己的SaveChanges)。

另一种方法是服务外观。Facade将是您业务层的公共接口,它将隐藏服务组合:

代码语言:javascript
复制
_firstService.SomeProcessing(data);
_secondService.SomeProcessing(data);
_unitOfWork.SaveChanges();

在这种情况下,UoW不会传递给控制器,而是传递给服务外观,服务外观将被注入控制器。如果您的业务逻辑将通过web服务(或其他远程技术)公开,您肯定会使用这种方法。

您必须处理的最后一个问题是将UoW传递给服务。将服务和UoW注入控制器(演示器、服务外观或其他任何东西),但同时必须将UoW (或ObjectContext)注入服务,以便内部使用的存储库能够使用它。为此,您需要正确的IoC生存期管理器,以便它为同一“请求”内的所有注入返回相同的实例。在web应用程序的情况下,您需要PerHttpRequest生命周期管理器(您必须自己实现它,因为团结没有提供它)。

票数 12
EN

Stack Overflow用户

发布于 2011-02-17 18:31:09

一种管理方法是使用http://mfelicio.wordpress.com/2010/02/07/managing-the-entity-framework-objectcontext-instance-lifetime-in-wcf-and-sharing-it-among-repositories/中描述的方法,本文为Wcf服务实现了ContextManager。对于ASP.NET应用程序,我们可以使用类似的东西。

代码语言:javascript
复制
public class AspNetDBContextManager<TContext> : IDBContextManager
    where TContext : IDBContext, new()
{
    #region IDBContextManager Members

    public IDBContext GetDBContext()
    {
        return this.GetOrCreateDbContext();
    }

    private IDBContext GetOrCreateDbContext()
    {
        if (HttpContext.Current == null)
        {
            throw new InvalidOperationException("Can be used only within ASP.NET applications");
        }

        string dbContextKey = string.Format("__AspNetDBCM__{0}__", HttpContext.Current.GetHashCode());

        object dbContext = HttpContext.Current.Items[dbContextKey];

        if (dbContext == null)
        {
            dbContext = new TContext();

            if (dbContext != null)
            {
                HttpContext.Current.Items[dbContextKey] = dbContext;
            }
        }

        return dbContext as IDBContext;
    }

    #endregion
}

public interface IDBContext
{
    object Context { get; }
}


public interface IDBContextManager
{
    IDBContext GetDBContext();
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5026265

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档