C# 3层asp.net mvc应用程序中的依赖项注入

C# 3层asp.net mvc应用程序中的依赖项注入,c#,asp.net-mvc,asp.net-mvc-4,dependency-injection,ninject,C#,Asp.net Mvc,Asp.net Mvc 4,Dependency Injection,Ninject,我有一个3层应用程序,层为: Web:表示层(ASP.NET MVC)-->仅查看BLL BLL:业务逻辑层-->仅查看DAL 数据访问层 所以Web层对我的DAL层一无所知。我的DAL中有存储库接口和具体类,它们用于业务逻辑类中的BLL层。问题是,为了解耦DAL和BLL,我如何设置Ninject将我的存储库实现注入BLL层 同样的问题是对于Web层和BLL层,我在BLL上有接口和实现,我在Web层中使用它们,我应该如何为此设置Niject?想法是为DAL和BLL定义接口。然后将此类接口的实

我有一个3层应用程序,层为:

  • Web:表示层(ASP.NET MVC)-->仅查看BLL
  • BLL:业务逻辑层-->仅查看DAL
  • 数据访问层
所以
Web
层对我的
DAL
层一无所知。我的
DAL
中有存储库接口和具体类,它们用于业务逻辑类中的
BLL
层。问题是,为了解耦
DAL
BLL
,我如何设置Ninject将我的存储库实现注入
BLL


同样的问题是对于
Web
层和
BLL
层,我在
BLL
上有接口和实现,我在
Web
层中使用它们,我应该如何为此设置Niject?

想法是为DAL和BLL定义接口。然后将此类接口的实例作为构造函数参数。范例

interface IDatabase
{
    // Methods here
}
您的BLL课程:

public class Bll
{
    IDatabase _db;
    public Bll(IDatabase db)
    {
        _db = db;
    }

    public void SomeMethod()
    {
        // Use db here
    }
}
然后在组合根目录中(在web应用程序中)使用内核配置这些依赖项:

 kernel.Bind<IDatabase>().To<ConcreteDatabase();

kernel.Bind().To我同意在使用Visual Studio的N层应用程序中使用依赖项注入时存在很多混乱

主要是因为在VisualStudio中,我们在解决方案中将层结构为不同的项目,并通过引用项目或DLL添加依赖项。这与DI和组合根概念的原则大不相同

基本问题是我们注入了什么依赖关系

业务逻辑还是存储库

如果它是存储库,那么您是对的,web层不需要知道它。它是基于特定条件选择存储库的BLL

如果我们有完全隔离的应用程序,我们需要在两个级别设置DI

您的web应用程序需要设置ninject来创建BLL组件。
BLL应用程序将设置ninject以创建一组特定的逻辑和存储库类。

我们在企业级应用程序中也遇到了这个问题。如何使用业务层和数据层中的类加载依赖项注入引擎,而不从web应用程序中创建对业务层和数据层的硬引用。我们最初玩了一些设计,并提出了这个非常成功的设计,已经为我们工作了18个月的生产至今,表现非常好

在web应用程序中的ninjectwebcommon文件中,使用反射访问业务层和数据层,以便加载所需的所有内容

像这样:

        System.Reflection.Assembly assembly;

        assembly = System.Reflection.Assembly.Load("our.biztier");
        kernel.Load(assembly);

        assembly = System.Reflection.Assembly.Load("our.datatier");
        kernel.Load(assembly);
Ninjects“Load”方法查找程序集中继承ninject类“NinjectModule”的任何类,然后调用它将所有内容加载到内核中

因此,我们的业务层和数据层都包含一个简单的注入类,用于加载所有内容

public class InjectionModuleBiz : NinjectModule
{


    public override void Load()
    {
        Kernel.Bind<ICustomerBiz>().To<CustomerBiz>().InRequestScope();
        Kernel.Bind<IEmployeeBiz>().To<EmployeeBiz>().InRequestScope();
    }
}
public类InjectionModuleBiz:NinjectModule
{
公共覆盖无效负载()
{
Kernel.Bind().To().InRequestScope();
Kernel.Bind().To().InRequestScope();
}
}
在我们的数据层中还有另一个injectionModule类

public class InjectionModuleData : NinjectModule
{


    public override void Load()
    {
        Kernel.Bind<ICustomerData>().To<CustomerData>().InRequestScope();
        Kernel.Bind<IEmployeeData>().To<EmployeeData>().InRequestScope();
    }
}
公共类InjectionModuleData:NinjectModule
{
公共覆盖无效负载()
{
Kernel.Bind().To().InRequestScope();
Kernel.Bind().To().InRequestScope();
}
}
最终的结果是,我们所有的业务层和数据层类都加载到我们的ioc容器中,并且可以在任何地方注入


希望这能有所帮助。

到目前为止,您都尝试了什么?最简单的方法是将DAL接口提供给BLL中的构造函数,然后设置一个Ninject模块来注入具体的类。但我有一种感觉,你已经知道了。首先,请看@MarkSeemann:我读到了,洋葱架构如何应用于3层应用程序?在此体系结构中:UI-->Domain@Ashkan-您没有完全理解这一点。DAL不会成为“最低层”。您将数据流与体系结构混淆了。是的,数据确实“向下”流动,数据库和DAL位于数据流的底部,但这并不意味着它必须以这种方式进行架构。好的,谢谢。我想我应该继续阅读这个主题…
,然后在你的组合根目录(在web应用程序中)中,你使用内核配置这些依赖关系,问题是在组合根目录中,我没有访问
DAL
接口和具体类的权限。如果你的依赖关系结构不同,你会这样做。你应该将web应用程序与所有内容联系起来,而将其他内容与任何内容联系起来。你可以阅读我的帖子来了解原因和方法。这里的解释有点长(因此这篇文章)。如果您有任何问题,请随时继续。您使用的是Ninject MVC扩展吗?您可以,尽管您也可以自己在博客文章中这样做,但您需要在Web应用层中添加对DLL的引用。