Dependency injection Ioc/DI-为什么我必须引用应用程序中的所有层/程序集';什么是切入点?

Dependency injection Ioc/DI-为什么我必须引用应用程序中的所有层/程序集';什么是切入点?,dependency-injection,inversion-of-control,castle-windsor,Dependency Injection,Inversion Of Control,Castle Windsor,(关于这个问题,) 我是DI的新手,所以请容忍我。我知道容器负责实例化我所有注册的类型,但为了做到这一点,它需要引用我的解决方案中的所有DLL及其引用 如果我不使用DI容器,我就不必在MVC3应用程序中引用EntityFramework库,只需引用我的业务层,它将引用我的DAL/Repo层 我知道在一天结束时,所有DLL都包含在bin文件夹中,但我的问题是必须通过VS中的“添加引用”明确引用它,以便能够发布包含所有必要文件的WAP 如果我不使用DI容器,我就不必在我的MVC3应用程序中引用Ent

(关于这个问题,)

我是DI的新手,所以请容忍我。我知道容器负责实例化我所有注册的类型,但为了做到这一点,它需要引用我的解决方案中的所有DLL及其引用

如果我不使用DI容器,我就不必在MVC3应用程序中引用EntityFramework库,只需引用我的业务层,它将引用我的DAL/Repo层

我知道在一天结束时,所有DLL都包含在bin文件夹中,但我的问题是必须通过VS中的“添加引用”明确引用它,以便能够发布包含所有必要文件的WAP

如果我不使用DI容器,我就不必在我的MVC3应用程序中引用EntityFramework库,只需要引用我的DAL/Repo层的业务层

是的,这正是DI努力避免的情况:)

对于紧密耦合的代码,每个库可能只有几个引用,但这些引用又有其他引用,创建了一个深度依赖关系图,如下所示:

因为依赖关系图很深,这意味着大多数库会拖拽许多其他依赖关系-例如,在图中,库C拖拽库H、库e、库J、库M、库K和库N。这使得独立于其他库重用每个库变得更加困难-例如

但是,在松散耦合的应用程序中,通过将所有引用移动到,依赖关系图被严重展平

如绿色所示,现在可以重用库C,而无需拖动任何不需要的依赖项

然而,尽管如此,对于许多DI容器,您不必向所有必需的库添加硬引用。相反,您可以使用基于约定的程序集扫描(首选)或XML配置形式的后期绑定

但是,在执行此操作时,必须记住将程序集复制到应用程序的bin文件夹,因为这不再自动发生。就我个人而言,我很少觉得这值得付出额外的努力

这个答案的更详细版本可以在我的书中找到

如果我没有使用DI容器,我就不必引用 我的MVC3应用程序中的EntityFramework库

即使在使用DI容器时,您也不必让MVC3项目引用EF,但您(隐式地)选择通过在MVC3项目中实现(组成对象图的启动路径)来实现这一点。如果您对使用程序集保护体系结构边界非常严格,则可以将表示逻辑移动到其他项目

当您将所有与MVC相关的逻辑(控制器等)从启动项目移动到类库时,它允许此表示层程序集与应用程序的其余部分保持断开连接。您的web应用程序项目本身将成为一个具有所需启动逻辑的薄壳。web应用程序项目将是引用所有其他程序集的组合根

在使用MVC时,将表示逻辑提取到类库会使事情变得复杂。因为控制器不在启动项目中(而视图、图像、css文件可能必须留在启动项目中),所以将所有内容连接起来将更加困难。这可能是可行的,但需要更多的时间来设置

由于缺点,我通常建议只将合成根保留在web项目中。许多开发人员不希望他们的MVC程序集依赖于DAL程序集,但这并不是一个真正的问题。不要忘记程序集是一个部署工件;您可以将代码拆分为多个程序集,以允许单独部署代码。另一方面,架构层是一个逻辑工件。在同一个部件中有多个层是很有可能的(也是很常见的)

在本例中,我们将在同一个web应用程序项目中(因此在同一个程序集中)拥有合成根(层)和表示层。即使该程序集引用了包含DAL的程序集,表示层仍然不引用数据访问层。这是一个很大的区别

当然,当您执行此操作时,编译器将无法在编译时检查此体系结构规则,但这不应该是一个问题。大多数体系结构规则实际上不能被编译器检查,而且总是有一些类似于常识的东西。如果你的团队没有常识,你可以随时使用代码审查(顺便说一句,每个团队都应该这样做)。您还可以使用诸如NDepend(这是一种商业工具)之类的工具,它可以帮助您验证体系结构规则。当您将NDepend与构建过程集成时,当有人签入违反此类体系结构规则的代码时,它会发出警告

在我的书的第四章中,你可以读到一篇更详细的关于作文根是如何工作的讨论

如果我没有使用DI容器,我就不必引用 我的MVC3应用程序中的EntityFramework库,仅我的业务层 将引用我的DAL/Repo层

您可以创建一个名为“DependencyResolver”的单独项目。 在这个项目中,您必须引用所有库

现在UI层不需要NHibernate/EF或任何其他与UI无关的库(Castle Windsor除外)来引用

如果您想从UI层隐藏Castle Windsor和DependencyResolver,可以编写一个调用IoC注册表的HttpModule

我只有StructureMap的一个示例:

public class DependencyRegistrarModule : IHttpModule
{
    private static bool _dependenciesRegistered;
    private static readonly object Lock = new object();

    public void Init(HttpApplication context)
    {
        context.BeginRequest += (sender, args) => EnsureDependenciesRegistered();
    }

    public void Dispose() { }

    private static void EnsureDependenciesRegistered()
    {
        if (!_dependenciesRegistered)
        {
            lock (Lock)
            {
                if (!_dependenciesRegistered)
                {
                    ObjectFactory.ResetDefaults();

                    // Register all you dependencies here
                    ObjectFactory.Initialize(x => x.AddRegistry(new DependencyRegistry()));

                    new InitiailizeDefaultFactories().Configure();
                    _dependenciesRegistered = true;
                }
            }
        }
    }
}

public class InitiailizeDefaultFactories
{
    public void Configure()
    {
        StructureMapControllerFactory.GetController = type => ObjectFactory.GetInstance(type);
          ...
    }
 }
DefaultControllerFactory不直接使用IoC容器,但它将委托给IoC容器方法

public class StructureMapControllerFactory : DefaultControllerFactory
{
    public static Func<Type, object> GetController = type =>
    {
        throw new  InvalidOperationException("The dependency callback for the StructureMapControllerFactory is not configured!");
    };

    protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
    {
        if (controllerType == null)
        {
            return base.GetControllerInstance(requestContext, controllerType);
        }
        return GetController(controllerType) as Controller;
    }
}
公共类结构MapControllerFactory:DefaultControllerFactory
{
公共街