Основы Виндзорского Замка (МОК) - PullRequest
3 голосов
/ 25 августа 2011

Я новичок в замке Виндзор и пытаюсь освоить основы ...

У меня есть следующий код ...

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".Если бы я хотел, чтобы он возвращал «Пока», что бы мне нужно было изменить, не меняя порядок классов?

Ответы [ 5 ]

1 голос
/ 26 августа 2011

Если вы используете 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();
}

Однако обычно, если вам нужен только один компонент из нескольких, просто не устанавливайте остальные - помещайте в контейнер только то, что вы хотитеэтот конкретный контекст.

1 голос
/ 25 августа 2011

Я предполагаю, что вы хотите использовать автоматическое подключение.Если нет, вы можете сделать ручную регистрацию для каждого из ваших компонентов.(Изменить: похоже, что вы обнаружили индивидуальную регистрацию самостоятельно :)).

См. Выбранный ответ на этот вопрос, чтобы использовать автоматическое подключение, но управляйте реализацией по умолчанию для конкретного типа:

Castle Windsor: использование регистрации соглашения вместе с конкретными реализациями

1 голос
/ 25 августа 2011

Я пришел с этим, который, казалось, работал ...

    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();
    }
0 голосов
/ 25 августа 2011

Вы можете либо зарегистрировать их с именем, либо ResolveAll и найти правильное.Однако то, что вы хотите сделать, не очень полезно в реальной жизни, потому что при регистрации нескольких реализаций вы, вероятно, захотите использовать все реализации.

0 голосов
/ 25 августа 2011

Я видел, что это сделано в XML, так что вы можете настроить его вне скомпилированных классов:

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

...