6

我开始从事一个新项目,我来自一个直接和“幼稚”的编程。

现在我关心的是使用 IoC 容器,特别是使用 Autofac 的依赖注入模式。

假设我有一个简单的会话工厂:

namespace Warehouse.Data
{
    public class SessionFactory
    {
        private static ISessionFactory _sessionFactory;
        private static ISystemSetting _systemSetting;

        SessionFactory(ISystemSetting systemSetting)
        {
            _systemSetting = systemSetting;

            InitializeSessionFactory();
        }

        private static void InitializeSessionFactory()
        {
            _sessionFactory = Fluently.Configure()
                .Database(DatabaseConfiguration)
                .Mappings(m => m.FluentMappings.AddFromAssemblyOf<MyMap>())
                .BuildSessionFactory();
        }

        public static ISession OpenSession()
        {
            return _sessionFactory.OpenSession();
        }
    }
}

在 Bootstrap.cs 中,我像这样配置 autofac:

namespace Warehouse.Infrastructure
{
    using Autofac;

    public class Bootstrap
    {
        public IContainer Configure()
        {
            var builder = new ContainerBuilder();

            builder.RegisterType<SystemSetting>().As<ISystemSetting>();
            builder.RegisterType<UserRepository>().As<IUserRepository>();

            return builder.Build();
        }
    }
}

我的问题是这样的:

  1. 如何使用 Autofac 解决 SessionFactory 对 ISystemSetting 的依赖?builder.Resolve<ISystemSetting>每次我想使用 SessionFactory 时都需要用作参数吗?
  2. 依赖注入模式,或者可能只是 Autofac,带有许多新词,例如 Service、Resolve、Singleton 等。我在哪里可以从头开始学习这些东西?其他所有 DI 框架都一样吗?
  3. 我需要了解 IoC 容器如何在具有多个层的项目中工作,每个层都需要引用 Autofac 吗?

谢谢你。

4

1 回答 1

9
  1. 你已经在你的引导程序中完成了它。

    builder.RegisterType<SystemSetting>().As<ISystemSetting>();
    

    这意味着每个依赖于 ISystemSettings 的对象都会获得一个 SystemSettings 实例。所以如果你使用

    var mySessionFactory = myContainer.Resolve<SessionFactory>();
    

    在你的代码中的某个地方(你真的应该在你的组合根目录中这样做)容器将为你完成这项工作。如果您有很多对象,并且具有多个依赖项,您将开始理解为什么 IoC 容器是“神奇的”;)

  2. 好吧 .. 很多 IoC 容器都使用了 resolve 这个词。它只是意味着“给我一个具有依赖关系的对象”。service 和 singleton 是来自面向对象设计语言的词。它们并不特定于 IoC 容器。你可以用谷歌搜索它们。我认为没有像这样的东西的总结。您将通过阅读书籍、文章和教程及时获得它。

  3. 不。实际上那是不行的。有一种称为 servicelocator 的模式,有些人认为它是一种反模式。如果您遵循这种模式,那么您的所有对象都只有一个依赖项,即容器!他们自己会从中得到他们需要的东西。

    public class MyClass
    {
        private DependencyOne dep1;
    
        public MyClass(WhatEverContainer container)
        {
            dep1 = container.Resolve<DependencyOne>();
        }
    }
    

    ...在这种情况下,您的容器将充当服务定位器,并且每个需要依赖项的对象都会要求服务定位器获取该依赖项。这将破坏 INVERSION 控制的整体价值并使您的对象依赖于容器。注入对象实际需要的东西,而不是它们需要的东西,以便找到它们实际需要的东西;D

    让您的对象与容器无关。并在您的组合根中使用您的容器,这就是您将应用程序的对象和层粘合在一起的地方。这里有一些东西要读:http ://blog.ploeh.dk/2011/07/28/CompositionRoot/

于 2013-05-08T11:54:22.780 回答