我应该在哪里创建工作实例股一个ASP.Net MVC 3应用程序? [英] Where should I create the Unit of Work instance in an ASP.Net MVC 3 application?

查看:154
本文介绍了我应该在哪里创建工作实例股一个ASP.Net MVC 3应用程序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我读过许多#1的职位,因为我可以找到关于内使用工作模式的单位
一个ASP.Net MVC 3应用程序,它包括业务层。不过,我仍然有一个与几个问题
关于这个话题,会大大AP preciate任何反馈的人可以给我。

I have read as many of the posts on Stackoverflow as I can find with regards the use of a Unit of Work pattern within an ASP.Net MVC 3 application which includes a Business Layer. However, I still have a couple of questions with regards this topic and would greatly appreciate any feedback people can give me.

我正在开发使用EF 4.1一个ASP.Net MVC 3 Web应用程序。我将使用这两个库和
这个项目类似于它们在<用过的工作模式的单位href=\"http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application\">this伟大的教程

I am developing an ASP.Net MVC 3 Web application which uses EF 4.1. I will be using both the Repository and Unit of Work Patterns with this project similar to how they are used in this great tutorial

在我的项目不同的是,我还需要包括业务层(在我的解决方案单独的项目),以
执行该应用程序的各种业务规则。上面提到的教程并没有一个业务层,
因此,从控制器创建工作类股的一个实例

The difference in my project is that I need to also include a Business Layer (separate project in my solution) in order to carry out the various business rules for the application. The tutorial mentioned above does not have a Business layer, and therefore creates an instance of the Unit of Work class from the controller

public class CourseController : Controller
{
    private UnitOfWork unitOfWork = new UnitOfWork();

不过,我的问题是,在那里我应该创建工作类股的情况下,如果我有一个业务层?

However, my question is, where should I create the instance of the Unit of Work class if I have a Business Layer?

我个人认为它应该在我的控制器中创建,然后注射到业务层像这样:

I personally think it should be created in my controller and then injected into the Business Layer like so:

public class PeopleController : Controller
{
    private readonly IUnitOfWork _UoW;
    private IPersonService _personService;

    public PeopleController()
    {
        _UoW = new UnitOfWork();
        _personService = new PersonService(_UoW);
    }

    public PeopleController(IUnitOfWork UoW, IPersonService personService)
    {
        _UoW = UoW;
        _personService = personService;

    }

    public ActionResult Edit(int id)
    {
        Person person = _personService.Edit(id);
        return View(person);
    }

public class UnitOfWork : IUnitOfWork, IDisposable
{
    private BlogEntities _context = new BlogEntities();
    private PersonRepository personRepository = null;

    public IPersonRepository PersonRepository
    {
        get
        {

            if (this.personRepository == null)
            {
                this.personRepository = new PersonRepository(_context);
            }
            return personRepository;
        }
    }

    public void Save()
    {
        _context.SaveChanges();
    }


public class PersonService : IPersonService
{
    private readonly IUnitOfWork _UoW;

    public PersonService(IUnitOfWork UoW)
    {
        _UoW = UoW;
    }

    public Person Edit(int id)
    {
         Person person = _UoW.PersonRepository.GetPersonByID(id);
         return person;
    }

public class PersonRepository : IPersonRepository
{
    private readonly BlogEntities _context;

    public PersonRepository(BlogEntities context)
    {
        _context = context;
    }

    public Person GetPersonByID(int ID)
    {
        return _context.People.Where(p => p.ID == ID).Single();
    }

我看过别人说,工作实例化的单位不应该在控制器,但服务层中创建
代替。为什么我不能肯定这种方法的原因是因为我的控制器可能要使用多个不同的
服务层在一个商业交易,如果工作实例股,每个服务的内部创建的,这将导致数
创建工作情况的单位,这违背了目的,即每商业交易一个工作单元。

I have read others saying that the Unit of Work instantiation should not be in the Controller, but created in the Service Layer instead. The reason why I am not so sure about this approach is because my Controller may have to use several different Service Layers in one business transaction, and if the Unit of Work instance was created inside each Service, it would result in several Unit of Work instances being created, which defeats the purpose, ie, one Unit of Work per business transaction.

也许我前面解释是错误的,但即便如此,我将不胜AP preciate如果有人可以把我的权利。

Maybe what I have explained above is wrong, but if so, I would greatly appreciate if someone could put me right.

再次感谢您的帮助。

推荐答案

我觉得你有一对夫妇的变化,使:

I think you have a couple of changes to make:.


  1. 让您的DI容器注入一个的UnitOfWork 实例为您服务类的构造函数,并把它从你的控制器完全的。

  1. Allow your DI container to inject a UnitOfWork instance into your Service classes in their constructors, and leave it out of your Controller altogether.

如果您的DI容器支持它(Ninject做,例如),配置你的的UnitOfWork 将在每个请求的基础管理;这样,您的服务将交由一个独特的的UnitOfWork 为每个请求,你就大功告成了。或...

If your DI container supports it (Ninject does, for example), configure your UnitOfWork to be managed on a per-request basis; this way your services will be handed a distinct UnitOfWork for each request, and you're all done. Or...

如果您的DI容器不支持每个请求的生命周期,配置管理的UnitOfWork 作为一个单身,所以每服务类获取相同的实例。然后更新存储在每个请求的基础对象的数据存储区的UnitOfWork 来存储它的实体对象,例如,在 HttpContext.Current.Items ,所描述的这里

If your DI container does not support per-request lifetimes, configure it to manage the UnitOfWork as a singleton, so every Service class gets the same instance. Then update your UnitOfWork to store its Entities object in a data store which stores objects on a per-request basis, for example in HttpContext.Current.Items, as described here.

修改1

对于其中的UnitOfWork 应注射;我想说的服务层是正确的位置。如果你想象你的系统作为一个系列赛里外层处理用户交互和较低层处理的数据存储层,每层应成为与用户不太关心,更关心的是数据存储。 的UnitOfWork 是从'低层'层的一个概念和控制器是从较高级别层;你的服务层它们之间的配合。因此,它是有道理的把的UnitOfWork 服务类,而不是控制器

Regarding where the UnitOfWork should be injected; I'd say the Service layer is the correct place. If you imagine your system as a series of layers where the outer layers deal with user interactions and the lower layers deal with data storage, each layer should become less concerned with users and more concerned with data storage. UnitOfWork is a concept from one of the 'lower-level' layers and Controller is from a higher-level layer; your Service layer fits between them. It therefore makes sense to put the UnitOfWork into the Service class rather than the Controller.

编辑2

要详细阐述的UnitOfWork 创建,它是关系到 HttpContext.Current.Items

To elaborate on the UnitOfWork creation and it's relationship to HttpContext.Current.Items:

的UnitOfWork 将不再持有到实体对象,将通过<$做参考C $ C>的HttpContext 对象,注入到的UnitOfWork 这样的界面背后:

Your UnitOfWork would no longer hold a reference to an Entities object, that would be done through the HttpContext object, injected into the UnitOfWork behind an interface like this:

public interface IPerRequestDataStore : IDisposable
{
    bool Contains(string key);

    void Store<T>(string key, T value);

    T Get<T>(string key);
}

的HttpContext 对象将然后实现 IPerRequestDataStore 是这样的:

The HttpContext object would then implement IPerRequestDataStore like this:

public class StaticHttpContextPerRequestDataStore : IPerRequestDataStore
{
    public bool Contains(string key)
    {
        return HttpContext.Current.Items.Contains(key);
    }

    public void Store<T>(string key, T value)
    {
        HttpContext.Current.Items[key] = value;
    }

    public T Get<T>(string key)
    {
        if (!this.Contains(key))
        {
            return default(T);
        }

        return (T)HttpContext.Current.Items[key];
    }

    public void Dispose()
    {
        var disposables = HttpContext.Current.Items.Values.OfType<IDisposable>();

        foreach (var disposable in disposables)
        {
            disposable.Dispose();
        }
    }
}

顺便说一句,我把它叫做 StaticHttpContextPerRequestDataStore ,因为它使用静态 HttpContext.Current 财产;这不是理想的单元测试(另一个话题完全),但至少其名称所表明的依赖的性质。

As an aside, I've called it StaticHttpContextPerRequestDataStore as it uses the static HttpContext.Current property; that's not ideal for unit testing (another topic altogether), but at least the name indicates the nature of its dependency.

的UnitOfWork 然后再将 IPerRequestDataStore 它给它的每个对象,使他们能够访问实体;这意味着,不管你如何创造出许多的UnitOfWork 情况下,您将使用相同​​的实体对象,因为各地的请求它的存储和检索的 IPerRequestDataStore

Your UnitOfWork then passes the IPerRequestDataStore it's given to each of its Repository objects so they can access the Entities; this means that no matter how many UnitOfWork instances you create, you'll use the same Entities object throughout a request because it's stored and retrieved in the IPerRequestDataStore.

您就会有一个抽象基这将使用其 IPerRequestDataStore 来延迟加载它实体对象是这样的:

You'd have an abstract base Repository which would use its IPerRequestDataStore to lazy-load its Entities object like this:

public abstract class RepositoryBase : IDisposable
{
    private readonly IPerRequestDataStore _dataStore;

    private PersonRepository personRepository;

    protected RepositoryBase(IPerRequestDataStore dataStore)
    {
        this._dataStore = dataStore;
    }

    protected BlogEntities Context
    {
        get
        {
            const string contextKey = "context";

            if (!this._dataStore.Contains(contextKey))
            {
                this._dataStore.Store(contextKey, new BlogEntities());
            }

            return this._dataStore.Get<BlogEntities>(contextKey);
        }
    }

    public void Dispose()
    {
        this._dataStore.Dispose();
    }
}

PeopleRepository (例如)应该是这样的:

Your PeopleRepository (for example) would look like this:

public class PeopleRepository : RepositoryBase, IPersonRepository
{
    public PeopleRepository(IPerRequestDataStore dataStore) 
        : base(dataStore)
    {
    }

    public Person FindById(int personId)
    {
        return this.Context.Persons.FirstOrDefault(p => p.PersonId == personId);
    }
}

最后,这里创建你的把PeopleController

IPerRequestDataStore dataStore = new StaticHttpContextDataStore();
UnitOfWork unitOfWork = new UnitOfWork(dataStore);
PeopleService service = new PeopleService(unitOfWork);
PeopleController controller = new PeopleController(service);

其中的一个核心概念在这里是对象有它们的依赖通过它们的构造函数注入其中;这通常被认为是很好的做法,也更容易让您从其他对象组成的对象。

One of the central concepts here is that objects have their dependencies injected into them via their constructors; this is generally accepted as good practice, and more easily allows you to compose objects from other objects.

这篇关于我应该在哪里创建工作实例股一个ASP.Net MVC 3应用程序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆