在 ASP.NET 中使用 Unity 进行依赖注入

Dependency Injection using Unity in ASP.NET

我有一个非常简单的设置。

namespace ObjectNamespace
{
    public class CustomProcessor : ICustomProcessor<myObject>
    {
        public CustomProcessorResult Execute(myObject Data)
        {
            try
            {
                var container = new UnityContainer();
                // UnityConfigurationSection section = new UnityConfigurationSection();

                var section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
                // this gives Microsoft.Practices.Unity.Configuration.UnityConfigurationSection
                section.Containers.Default.Configure(container);

                var configuration = Container.Resolve<ICustomProcessorConfiguration>(); 
                var emailer = container.Resolve<IEmailManager>(); 
                var reportGenerator = container.Resolve<IReportGenerator>();  
            }
            catch (Exception e)
            {
                Trace.WriteLine("It failed while trying to initialize the DI componenets");
                throw;
            }

错误消息是空引用异常。它显示在

section.Containers.Default.Configure(Container);

我的部分返回我在 web.config 文件中的值,该文件在该行 (Microsoft.Practices.Unity.Configuration.UnityConfigurationSection)

上进行了注释

为了实现这个 Execute 方法,我束手无策。我不知道为什么它会给我一个空引用错误。 Container 应该由 UnityConfigurationSection 配置。

这是我在 <configSections> 标签内的 web.config 文件

<section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, myCustom.dll" />

据我所知,这就是如何解析和绑定到接口。我做错了什么吗?

是否有其他方法可以设置版块?或配置容器?在解决之前?

编辑: 在下面提供的一个答案之后,我试图跳过代码的 section 部分,但是DI 组件仍然没有被初始化,因为它说 "header comments" are missing 这是它在配置文件中查看的内容。这就是应用程序的设置方式。所以我猜想从配置 "unity" section 中获取值是必不可少的。有什么办法可以将 section 部分合并到我的代码中吗?让它配置我的容器?

我已经在 myApp.cfg 文件中为 DI 映射了我的 <unity> 标签(例如:用于电子邮件)

<type type= "myProject.Interfaces.IEmailManager, mySolution (dll name)"
    mapTo="myProject.EmailManager,  mySolution (dll name)" >
<lifetime type="singleton"/>
</type>

所以在另一个建议之后,我删除了所有基于 XML unity 的集成代码,并且我从 Unity 获得了 ResolutionFailedException。我已经取消了所有 xml 集成并按照建议进行了注册,但现在我得到了 build operation failed, Required attribute , 'header comment' not found。我什至在 myApp.cfg 中设置了一个别名作为 ControlledLifetimeManager 的 typeAlias,我也把它去掉了。没有统一参考,这是我得到的错误。它试图从 web.config 第 43 行读取并给我这个错误。没有任何需要或我知道的 header 评论注册。

Are there any alternative ways of setting up a section? or configuring the container? before resolving it?

是的。不需要使用 XML 配置,除非您的应用程序需要在不重新编译的情况下更改组件(通常情况下不会发生这种情况)。 XML 配置现在大多被认为是配置 DI 容器的过时方法。与基于代码的配置相比,维护起来既脆弱又耗时。

您可以改为使用流畅的 API and/or container extensions 来配置您的组件。下面是流利的例子 API:

// Begin composition root
var container = new UnityContainer();

// This is the equivalent to the XML registration 
// code you show in your question 
container.RegisterType<IEmailManager, EmailManager>(new ContainerControlledLifetimeManager());
// End composition root

IEmailManager emailManager = container.Resolve<IEmailManager>();

组合根应该设置在应用程序的入口点。在 ASP.NET 中,它将在 Global.asax 文件的 Application_Start 事件中。

当然,您需要删除为 XML 配置设置的任何代码 + 为 Unity 设置的任何 XML 元素,否则您可能会从 Unity 中得到错误尝试加载这些元素。

附加信息:

http://blog.ploeh.dk/2011/07/28/CompositionRoot/