在MVC项目中从控制器访问服务层

Rob*_*ous 2 asp.net-mvc asp.net-mvc-3 asp.net-mvc-4

我以前有一个控制器,其代码如下:

public ActionResult Method(int Id)
        {
            var foo = doThis(Id)
            return View("Error");
        }
Run Code Online (Sandbox Code Playgroud)

doThis() 是控制器中存在的一个方法,并执行一些逻辑。我现在尝试将所有业务逻辑重新定位到包含一堆类的服务项目。

首先,我添加了一个类库 Project.Services,然后添加了一个类 FooServices,其中包含以下内容:

namespace Project.Services
{
    class FooServices
    {
        public List<Bar> doThis(int Id)
        {
            //Do stuff
            return parentSets;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我已经从我的 MVC 项目添加了对此项目的引用,并从该服务项目添加了对我的数据模型项目的引用,但我不确定现在如何继续。如何从控制器访问这些方法?

Dar*_*rov 5

如何从控制器访问这些方法?

为了访问实例方法,您需要该对象的实例:

public ActionResult Method(int Id)
{
    var foo = new FooServices().doThis(Id)
    return View("Error");
}
Run Code Online (Sandbox Code Playgroud)

当然,通过这样做,您现在将控制器逻辑与服务的特定实现紧密耦合,使得单独测试控制器变得非常困难。

因此,要弱化耦合,首先要引入抽象:

public interface IFooServices
{
    List<Bar> DoThis(int id)
}
Run Code Online (Sandbox Code Playgroud)

然后让你的服务层实现这个接口:

public class FooServices: IFooServices
{
    public List<Bar> DoThis(int id)
    {
        //Do stuff
        return parentSets;
    }
}
Run Code Online (Sandbox Code Playgroud)

好吧,现在你的控制器可以使用这个抽象了:

public class HomeController: Controller
{
    private readonly IFooServices service;
    public HomeController(IFooServices service)
    {
        this.sevrice = service;
    }

    public ActionResult Method(int id)
    {
        var foo = this.service.DoThis(id)
        return View("Error");
    }
}
Run Code Online (Sandbox Code Playgroud)

太好了,在这个阶段,我们的控制器和服务层之间确实存在弱耦合。现在剩下的就是配置您最喜欢的依赖注入框架以将特定服务注入到您的控制器中。