了解依赖注入,MVC nTier 应用程序中的 IoC
Understanding Dependency Injection, IoC in a MVC nTier Application
我了解 DI 和 IoC,但我似乎无法理解如何在 nTier 应用程序中实现它。这是我尝试使用一个域对象构建的简单 MVC 应用程序。
层:DAL 和 UI 将引用 BLL 层。
DAL<--BLL-->UI
DAL 将包含 EntityFramework、SQLBlogRepository、Blog.cs 和 Mapper
BAL 将包含 IBlogRepository,域对象:Blog.cs
UI 将实现 IBlogRepository 的 Constructor DI
这就是我卡住的地方。我如何使用 Ninject 以便构造函数知道使用 SqlBlogRepository 实现?我还将 运行 放入了一些使用 "Composition Root" 的示例中,这增加了更多的混乱。然后是使用存储库模式的示例。最重要的是,我正在尝试实现一个松散耦合并使用 IoC/Dependency 注入的 nTier MVC 应用程序。请帮助我规划如何从 UI 层进行调用并通过 BLL 层获取 DAL 层 return 数据,同时所有三个层都是松散耦合的。
我假设您没有创建 ninject 配置文件。所以这就是我们在我所在的地方是如何做到的。
解释我在做什么。您需要让您的具体 class 实现您想要使用的任何接口。
在 ninject 配置文件中,您需要将接口绑定到具体的 classes。然后你可以调用 ninject 来获取你的接口,它将 return 你想要的具体 class。
如果您想在 N 层开发环境中使用它。
DAL <- >BL <->UI
我们将 ninject 配置卡在了 BL 中。因为 BI 是唯一引用 DAL 的层。我们通过引用将 DAL interfaces/concrete classes 暴露给 BL。然后在BL中我们添加了Ninject配置。
一旦在 UI 中完成,我们就能够访问所有业务对象。
DAL
public interface IRepository
{
//does some things
}
public SQLBlogRepository : IRepository
{
//implements IRepository
}
BL
NINJECT 配置文件
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。所以你不需要自己创建它。配置文件将处理构造函数中的所有依赖项。所以你永远不需要知道你需要做什么构造函数创建。您还可以在一个地方更改创作并通过您的代码自动将其传播出去。
在您的示例中,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);
}
}
我了解 DI 和 IoC,但我似乎无法理解如何在 nTier 应用程序中实现它。这是我尝试使用一个域对象构建的简单 MVC 应用程序。
层:DAL 和 UI 将引用 BLL 层。 DAL<--BLL-->UI
DAL 将包含 EntityFramework、SQLBlogRepository、Blog.cs 和 Mapper BAL 将包含 IBlogRepository,域对象:Blog.cs UI 将实现 IBlogRepository 的 Constructor DI
这就是我卡住的地方。我如何使用 Ninject 以便构造函数知道使用 SqlBlogRepository 实现?我还将 运行 放入了一些使用 "Composition Root" 的示例中,这增加了更多的混乱。然后是使用存储库模式的示例。最重要的是,我正在尝试实现一个松散耦合并使用 IoC/Dependency 注入的 nTier MVC 应用程序。请帮助我规划如何从 UI 层进行调用并通过 BLL 层获取 DAL 层 return 数据,同时所有三个层都是松散耦合的。
我假设您没有创建 ninject 配置文件。所以这就是我们在我所在的地方是如何做到的。
解释我在做什么。您需要让您的具体 class 实现您想要使用的任何接口。
在 ninject 配置文件中,您需要将接口绑定到具体的 classes。然后你可以调用 ninject 来获取你的接口,它将 return 你想要的具体 class。
如果您想在 N 层开发环境中使用它。
DAL <- >BL <->UI
我们将 ninject 配置卡在了 BL 中。因为 BI 是唯一引用 DAL 的层。我们通过引用将 DAL interfaces/concrete classes 暴露给 BL。然后在BL中我们添加了Ninject配置。
一旦在 UI 中完成,我们就能够访问所有业务对象。
DAL
public interface IRepository
{
//does some things
}
public SQLBlogRepository : IRepository
{
//implements IRepository
}
BL
NINJECT 配置文件
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。所以你不需要自己创建它。配置文件将处理构造函数中的所有依赖项。所以你永远不需要知道你需要做什么构造函数创建。您还可以在一个地方更改创作并通过您的代码自动将其传播出去。
在您的示例中,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);
}
}