【问题标题】:Castle Windsor (IOC) Basics温莎城堡 (IOC) 基础知识
【发布时间】:2011-08-25 12:22:59
【问题描述】:

我是温莎城堡的新手,正在尝试了解基础知识...

我有以下代码...

namespace WindowsBash.Models
{
    public interface IShouter
    {
        string Display();
    }

    public class Shout : IShouter
    {
        private IMessage _message;

        public Shout(IMessage message)
        {
            _message = message;
        }        

        public string Display()
        {
            return _message.TheMessage();
        }
    }

    public interface IMessage
    {
        string TheMessage();
    }

    public class MessageHello : IMessage
    {
        public string TheMessage()
        {
            return "Hello";
        }
    }

    public class MessageBye : IMessage
    {
        public string TheMessage()
        {
            return "Bye";
        }
    }
}

然后我有以下方法来尝试测试温莎正在做什么......

private void TestIOC()
{
    var container = new WindsorContainer();
    container.Register(
        AllTypes.FromAssemblyContaining<IShouter>()
                .Where(x => x.Namespace.StartsWith("WindowsBash"))
                .WithService.AllInterfaces());

    var MyShouter = container.Resolve<IShouter>();
    var result = MyShouter.Display();
}

现在这总是返回“Hello”。如果我想让它返回“Bye”,我需要在不改变类顺序的情况下改变什么?

【问题讨论】:

    标签: c# castle-windsor


    【解决方案1】:

    我假设您想使用自动连线。如果没有,您可以为每个组件进行手动注册。 (编辑:看起来你自己发现了一对一的注册:))。

    查看此问题的所选答案以使用自动装配但控制特定类型的默认实现:

    Castle Windsor: Using convention registration along with specific implementations

    【讨论】:

    • 谢谢,这帮助最大。我可以看到自动布线的好处是要走的路。
    【解决方案2】:

    我想出了这个似乎可行的方法......

        private void TestIOC()
        {
            var container = BootstrapContainer();
            container.Register(
                Component.For<IShouter>().ImplementedBy<Shout>(),
                Component.For<IMessage>().ImplementedBy<MessageBye>());
    
            var shell = container.Resolve<IShouter>();
            var result = shell.Display();
    
            container.Dispose();
        }
    

    【讨论】:

      【解决方案3】:

      如果您使用的是 Windsor 3:

      private void TestIOC()
      {
          var container = new WindsorContainer();
          container.Register(
              AllTypes.FromAssemblyContaining<IShouter>()
                      .Where(x => x.Namespace.StartsWith("WindowsBash"))
                      .WithService.AllInterfaces()
                      .ConfigureFor<MessageBye>(c => c.IsDefault()));
      
          var MyShouter = container.Resolve<IShouter>();
          var result = MyShouter.Display();
      }
      

      但是,通常如果您只想要几个组件中的一个,则不要安装其他组件 - 只将您想要的特定上下文放入容器中。

      【讨论】:

        【解决方案4】:

        我已经在 XML 中看到了这一点,因此您可以在已编译的类之外对其进行配置:

        http://www.castleproject.org/container/documentation/v21/usersguide/externalconfig.html

        【讨论】:

        • 谢谢,但我想通过调整 TestIOC 方法在代码中做到这一点。
        【解决方案5】:

        您可以使用名称注册它们,或者 ResolveAll 并找到正确的名称。但是,您想要做的事情在现实生活中并没有真正有用,因为在注册多个实现时,您可能希望使用所有实现。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多