【问题标题】:Understanding Dependency Injection, IoC in a MVC nTier Application了解 MVC nTier 应用程序中的依赖注入和 IoC
【发布时间】:2016-09-08 20:00:54
【问题描述】:

我了解 DI 和 IoC,但我似乎无法了解如何在 nTier 应用程序中实现它。这是我尝试使用一个域对象构建的简单 MVC 应用程序。

层:DAL 和 UI 将引用 BLL 层。 DALUI

DAL 将包含 EntityFramework、SQLBlogRepository、Blog.cs 和 Mapper BAL 将包含 IBlogRepository,域对象:Blog.cs UI 将实现 IBlogRepository 的 Constructor DI

这就是我卡住的地方。如何使用 Ninject 让构造函数知道使用了 SqlBlogRepository 实现?我还遇到了一些使用“Composition Root”的例子,这增加了更多的混乱。然后是使用存储库模式的示例。底线是,我正在尝试实现一个松散耦合并使用 IoC/依赖注入的 nTier MVC 应用程序。请帮我规划一下如何从 UI 层进行调用并让 DAL 层通过 BLL 层返回数据,而所有三层都是松散耦合的。

【问题讨论】:

  • 你看过the onion architecture吗?将您的依赖项,即 DAL、其他基础设施放在外部,并将它们注入核心(域/BLL)。也发现了这个:codeproject.com/Articles/808400/…
  • 谢谢 Mark C。我一定会阅读有关洋葱架构的信息并查看示例。我真的很感激。

标签: c# dependency-injection asp.net-mvc-5 ninject inversion-of-control


【解决方案1】:

我假设您没有创建 ninject 配置文件。所以这就是我们在我所在的地方是如何做到的。

解释我在做什么。你需要让你的具体类实现你想使用的任何接口。

在 ninject 配置文件中,您需要将接口绑定到具体类。然后你可以调用 ninject 来获取你的接口,它会返回你想要的具体类。

如果您想在 N 层开发环境中使用它。

DAL BL UI

我们将 ninject 配置固定在 BL 中。因为 Bl 是唯一引用 DAL 的层。我们通过引用向 BL 公开了 DAL 接口/具体类。然后在 BL 中我们添加了 Ninject 配置。

一旦在 UI 中完成,我们就可以访问所有业务对象。

ninject starter tutorial

DAL

public interface IRepository
{
   //does some things
}

public SQLBlogRepository : IRepository
{
//implements IRepository
}

BL

忍者配置文件

public Foo : IFOO
{
     public Foo(IRepository steve){}
}

public interface IFOO
{
}

public class NinjectConfig : NinjectModule
{
    public override void Load()
    {
      Bind<IRepository>.To<SQLBlogRepository>();
      Bind<IFOO>.To<Foo>();
     }
}

然后你就这样使用它。

var repo = new StandardKernel(new NinjectConfig()).Get<IRepository>();
var fooManager = new StandardKernel(new NinjectConfig()).Get<IFOO>();

var fooManager,通过 ninject 的力量将自动实例化你的 repo。所以你不需要自己创建它。配置文件将处理构造函数中的所有依赖项。所以你永远不需要知道你需要做什么构造函数。您还可以在一处更改创作并通过您的代码自动将其传播出去。

【讨论】:

  • 谢谢,明天我要试试这个明天的方法。快速提问,所以我不再需要在控制器构造函数中传递 IRepository 了吗?
  • 正确,Ninject 将查看您在负载中绑定的具体类中的构造函数。如果它在构造函数中看到它有绑定的参数,它将自动实例化该对象并将其传入。
【解决方案2】:

在您的示例中,UI(Mvc 项目)是您的组合根,您可以在其中配置您的依赖项(使用任何 ioc 容器,如 ninject)。您的 mvc 项目必须具有对 BLL 和 DAL 层的引用,并且您必须在您的 mvc 项目中进行类似 @gh9 answer 的映射。

在你的控制器中

public class HomeController : Controller
{
    private readonly IFOO _fooBll;
    public HomeController(IFOO fooBll){
    _fooBll=fooBll;
     }
    public ActionResult Index()
    {
        return View();
    }
}

你必须有一个控制器工厂来解决你的控制器依赖,比如:

public class NinjectControllerFactory : DefaultControllerFactory
{
    private IKernel ninjectKernel;

    public NinjectControllerFactory()
    {
        ninjectKernel = new StandardKernel();
    }

    protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
    {
        return controllerType == null
               ? null
               : (IController) ninjectKernel.Get(controllerType);
    }
}

【讨论】:

  • 现在我有点配置。你是说除了Ninject配置文件,我还要实现一个控制器工厂?
  • 我建议你的 mvc 层应该不硬引用你的 DAL,否则你所做的就是拆分项目。
  • @zXSwordXz 如果你想注入你的控制器,你必须使用控制器工厂
  • @Eonasdan 如果 mvc 项目对 DAL 项目有硬引用,有什么问题?
  • @M.Azad 这不会违反 SoC 吗?我的猜测是 UI 应该只有对 BLL 和 Core/Common 层的硬引用。否则,您的同行开发人员可以开始直接向您的 DAL 编写代码(将业务逻辑放入您的 UI)。破坏 BLL 层的目的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-12-12
  • 2018-10-31
  • 2023-03-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多