在类库中使用Autofac

时间:2012-05-23 18:19:22

标签: asp.net-mvc-3 ioc-container autofac

我正在尝试解决Autofac IoC容器的问题。

我的网络应用程序包含以下部分:

  1. 网络应用
  2. 核心(共享)库。
  3. 模块
  4. 每个模块都有对核心库的引用(包括下面的代码),每个模块必须能够注册自己的类型。因此,我需要在应用程序和模块之间有一个共享容器。

    我有以下容器的代码:

    public static class DependencyContainer
        {
            public static IContainer Container { get; private set; }
    
            public static ContainerBuilder Builder { get; private set; }
    
            public static void RegisterType<TFrom, TTo>() where TTo : TFrom
            {
                Builder.RegisterType<TTo>().As<TFrom>();
            }
    
            public static T ResolveType<T>()
            {
                return Container.Resolve<T>();
            }
    
            public static void InitContainer()
            {
                Builder = new ContainerBuilder();
                Container = Builder.Build();
            }
        }
    

    此容器位于主(核心)库中。应用程序启动时,它从global.asax调用InitContainer()。在此之后我尝试使用RegisterType()方法从我的应用程序模块注册一个新类型。

    但在此之后我无法解决任何类型。它只是抛出了这种类型未注册的异常。

    此代码的主要思想是,我将能够使用一个共享容器从任何模块和Web应用程序解析任何类型。

    有人可以帮我解决这个问题吗?在多个库之间使用一个共享IoC容器是否有更优雅的架构解决方案?

    提前致谢!

2 个答案:

答案 0 :(得分:3)

您的设计导致Service Locator anti-pattern。防止在核心库中定义容器并让每个人都引用它。使用依赖注入并在Composition Root中配置容器,即应用程序的启动路径(在您的情况下,组合根将成为Web应用程序的一部分)。

您可以利用Autofac Module feature,在合成根目录中,您可以注册此模块。

builder.RegisterModule(new CarTransportModule());

但您可以将模块注册类定义为静态,这甚至更简单:

MyApp.SomeModule.SomeModuleBootstrapper.Register(builder);

答案 1 :(得分:1)

问题解决了 - 我们只需要在注册所有依赖项后调用container.Build()......