Autofac依赖注入实现

时间:2013-04-26 09:17:08

标签: c# .net dependency-injection inversion-of-control

我开始研究一个新项目,我来自一个直接的,天真的'编程。

现在我关于使用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? 每次我想使用SessionFactory时,是否需要使用builder.Resolve<ISystemSetting>作为参数?
  2. 依赖注入模式,或者只是Autofac,带有许多新词,如Service,Resolve,Singleton等。我在哪里可以从头学习这些东西?每个其他DI框架都一样吗?
  3. 我需要了解IoC Container如何在具有多个图层的项目中工作,每个图层都需要引用Autofac吗?
  4. 谢谢。

1 个答案:

答案 0 :(得分:8)

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

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

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

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

  2. 好吧..很多IoC容器使用的是单词resolve。它只是意味着“给我一个具有依赖性的对象”。 服务和单身是来自面向对象设计的语言。它们不是特定于IoC容器的。你可以谷歌了。对于像这样的东西,我认为没有总结。你会通过阅读书籍,文章和阅读教程来及时得到它。

  3. 没有。实际上那是不行的。有一种叫做servicelocator的模式,有些人认为它是反模式。如果你遵循这种模式,你的所有对象都只有一个依赖,即容器!并且他们自己摆脱了他们所需要的东西。

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

    ...在这种情况下,您的容器将充当servicelocator,并且每个需要依赖的对象都会要求servicelocator获取该依赖关系。 这将破坏控制的INVERSION的整个价值,并使你的对象依赖于容器。注入对象实际需要的东西,而不是他们需要什么以找到他们实际需要的东西; D

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