【问题标题】:Can Castle.Windsor do automatic resolution of concrete typesCastle.Windsor 可以自动解析具体类型吗
【发布时间】:2010-12-29 15:51:01
【问题描述】:

我们正在为 C# 项目评估 IoC 容器,Unity 和 Castle.Windsor 都脱颖而出。我喜欢 Unity 的一件事(NInject 和 StructureMap 也这样做)是,那些很明显如何构造它们的类型不必在 IoC 容器中注册。

Castle.Windsor 有没有办法做到这一点?我对 Castle.Windsor 说它不这样做是公平的吗?是否有故意不这样做的设计理由,或者是疏忽,或者只是不被视为重要或有用?

我知道温莎的container.Register(AllTypes...,但这并不完全相同。它不是完全自动的,而且范围很广。

为了说明这一点,这里有两个 NUnit 测试通过 Unity 和 Castle.Windsor 做同样的事情。 Castle.Windsor 失败了。 :

namespace SimpleIocDemo
{
    using NUnit.Framework;
    using Castle.Windsor;
    using Microsoft.Practices.Unity;

    public interface ISomeService
    {
        string DoSomething();
    }

    public class ServiceImplementation : ISomeService
    {
        public string DoSomething()
        {
            return "Hello";
        }
    }

    public class RootObject
    {
        public ISomeService SomeService { get; private set; }

        public RootObject(ISomeService service)
        {
            SomeService = service;
        }
    }

    [TestFixture]
    public class IocTests
    {
        [Test]
        public void UnityResolveTest()
        {
            UnityContainer container = new UnityContainer();
            container.RegisterType<ISomeService, ServiceImplementation>();
            // Root object needs no registration in Unity
            RootObject rootObject = container.Resolve<RootObject>();
            Assert.AreEqual("Hello", rootObject.SomeService.DoSomething());
        }

        [Test]
        public void WindsorResolveTest()
        {
            WindsorContainer container = new WindsorContainer();
            container.AddComponent<ISomeService, ServiceImplementation>();

            // fails with exception "Castle.MicroKernel.ComponentNotFoundException: 
            // No component for supporting the service SimpleIocDemo.RootObject was found"
            // I could add
            // container.AddComponent<RootObject>();
            // but that approach does not scale
            RootObject rootObject = container.Resolve<RootObject>();
            Assert.AreEqual("Hello", rootObject.SomeService.DoSomething());
        }
    }
}

【问题讨论】:

标签: .net inversion-of-control castle-windsor unity-container ioc-container


【解决方案1】:

Windsor 不支持开箱即用,这是一个深思熟虑的决定。详情请见this answer

但是,以后的版本可以很容易地扩展以支持这种情况,方法是根据请求延迟注册未注册的组件。 您必须实现ILazyComponentLoader 接口,这将占用大约5 行代码。示例见here

尽管我在 2018 年的建议与 2009 年的建议相同 - 除非在 非常 特定情况下您有 非常 充分的理由选择这种方法而不是替代方法

【讨论】:

  • 你能谈谈这个决定背后的想法吗?它似乎有好处,所以你一定看到了更大的成本。我会假设隐式注册会有短暂的生活方式,但也许这个假设只是一个假设,它很容易引起混淆。
猜你喜欢
  • 1970-01-01
  • 2016-01-12
  • 2018-06-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-12
  • 1970-01-01
相关资源
最近更新 更多