EF6(代码优先)、MVC、Unity 和没有存储库的服务层 [英] EF6 (code first), MVC, Unity, and a service layer without a repository

查看:19
本文介绍了EF6(代码优先)、MVC、Unity 和没有存储库的服务层的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的应用程序正在使用 SQL Server 2012、EF6、MVC 和 Web API.

My application is using SQL Server 2012, EF6, MVC and Web API.

它还使用存储库和各种文件,例如:

It's also using a repository and assorted files such as:

DatabaseFactory.cs
Disposable.cs
IDatabaseFactory.cs
IRepository.cs
IUnitOfWork.cs
RepositoryBase.cs
UnitOfWork.cs

我们已经在控制器和存储库之间使用了一个服务层对于一些复杂的业务逻辑.我们没有计划改变到不同的数据库,它已经被指出对我来说,最近的想法是 EF6 是一个存储库,所以为什么要构建上面还有另一个存储库,为什么上面有我所有的文件.

We already use a service layer between our controllers and the repository for some complicated business logic. We have no plans EVER to change to a different database and it has been pointed out to me that the recent thinking is that EF6 is a repository so why build another repository on top of it and why have all of the files I have above.

我开始认为这是一种明智的做法.

I am starting to think this is a sensible approach.

有没有人知道任何没有实现 EF6 的示例存储库,带有服务层.我在网上的搜索发现了很多复杂的代码示例似乎无缘无故地过于复杂.

Does anyone know of any examples out there that implement EF6 without a repository, with a service layer. My search on the web has revealed many complex code examples that seem over complicated for no reason at all.

我的问题也是在使用服务层时,我该放在哪里:

My problem is also when using a Service Layer then where do I put:

context = new EFDbContext()

在控制器、服务层还是两者兼而有之?我读到我可以通过依赖注入来做到这一点.我已经将 Unity 用作 IOC,但我不知道该怎么做.

In the controller, the service layer or both ? I read that I can do this with dependancy injection. I already use Unity as an IOC but I don't know how I can do this.

推荐答案

如果您安装并添加 Unity.Mvc*,为 ASP.NET MVC 和 WebAPI 设置 Unity 非常简单>Unity.WebAPI* Nuget 包到您的项目.(* 是版本号,例如 3、4 或 5.为您的项目寻找合适的版本.例如链接 到 Unity.Mvc 5 包到 Unity.WebAPI5个包.)

Setting up Unity for ASP.NET MVC and WebAPI is quite easy if you install and add the Unity.Mvc* and Unity.WebAPI* Nuget packages to your project. (The * is a version number, like 3 or 4 or 5. Look for the appropriate versions for your project. Here are for example the links to the Unity.Mvc 5 package and to the Untity.WebAPI 5 package.)

这篇博文

The usage of these packages is explained in this blog post.

构建块大致是这样的:

您构建一个统一容器并在其中注册所有依赖项,尤其是 EF 上下文:

You build a unity container and register all your dependencies there, especially the EF context:

private static IUnityContainer BuildContainer()
{
    var container = new UnityContainer();

    container.RegisterType<MyContext>(new HierarchicalLifetimeManager());

    container.RegisterType<IOrderService, OrderService>();
    container.RegisterType<ICustomerService, CustomerService>();
    container.RegisterType<IEmailMessenger, EmailMessenger>();
    // etc., etc.

    return container;
}

MyContext 是您的派生 DbContext 类.使用 HierarchicalLifetimeManager 注册上下文非常重要,因为它将确保每个 Web 请求的新上下文将在每个请求结束时由容器实例化和释放.

MyContext is your derived DbContext class. Registering the context with the HierarchicalLifetimeManager is very important because it will ensure that a new context per web request will be instantiated and disposed by the container at the end of each request.

如果您的服务没有接口,而只有具体的类,您可以删除上面注册接口的行.如果需要将服务注入控制器,Unity 只会创建具体服务类的实例.

If you don't have interfaces for your services but just concrete classes you can remove the lines above that register the interfaces. If a service needs to be injected into a controller Unity will just create an instance of your concrete service class.

一旦你构建了容器,你就可以在 global.asax 中的 Application_Start 中将它注册为 MVC 和 WebAPI 的依赖解析器:

Once you have built the container you can register it as dependency resolver for MVC and WebAPI in Application_Start in global.asax:

protected void Application_Start()
{
    var container = ...BuildContainer();

    // MVC
    DependencyResolver.SetResolver(
        new Unity.MvcX.UnityDependencyResolver(container));

    // WebAPI
    GlobalConfiguration.Configuration.DependencyResolver =
        new Unity.WebApiX.UnityDependencyResolver(container);
}

一旦设置了 DependencyResolver,如果参数可以使用注册的类型解析,框架就能够实例化在其构造函数中接受参数的控制器.例如,您现在可以创建一个 CustomerController 来获取 CustomerService 和一个 EmailMessenger 注入:

Once the DependencyResolvers are set the framework is able to instantiate controllers that take parameters in their constructor if the parameters can be resolved with the registered types. For example, you can create a CustomerController now that gets a CustomerService and an EmailMessenger injected:

public class CustomerController : Controller
{
    private readonly ICustomerService _customerService;
    private readonly IEmailMessenger _emailMessenger;

    public CustomerController(
        ICustomerService customerService,
        IEmailMessenger emailMessenger)
    {
        _customerService = customerService;
        _emailMessenger = emailMessenger;
    }

    // now you can interact with _customerService and _emailMessenger
    // in your controller actions
}

这同样适用于 WebAPI 的派生 ApiController.

The same applies to derived ApiControllers for WebAPI.

服务可以依赖上下文实例与实体框架交互,如下所示:

The services can take a dependency on the context instance to interact with Entity Framework, like so:

public class CustomerService // : ICustomerService
{
    private readonly MyContext _myContext;

    public CustomerService(MyContext myContext)
    {
        _myContext = myContext;
    }

    // now you can interact with _myContext in your service methods
}

当 MVC/WebAPI 框架实例化一个控制器时,它将注入注册的服务实例并解析它们自己的依赖关系,即将注册的上下文注入服务构造函数.您将注入控制器的所有服务将在单个请求期间接收相同的上下文实例.

When the MVC/WebAPI framework instantiates a controller it will inject the registered service instances and resolve their own dependencies as well, i.e. inject the registered context into the service constructor. All services you will inject into the controllers will receive the same context instance during a single request.

使用此设置,您通常不需要 context = new MyContext()context.Dispose(),因为 IOC 容器将管理上下文生命周期.

With this setup you usually don't need a context = new MyContext() nor a context.Dispose() as the IOC container will manage the context lifetime.

这篇关于EF6(代码优先)、MVC、Unity 和没有存储库的服务层的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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