Где и как Замок Виндзор устанавливает каротаж

Я новичок в Castle Windsor и смотрю на вход и выход из каротажа. Это кажется довольно впечатляющим, но единственное, что я не могу решить, - это то, где Windsor устанавливает свойство Logger на мои классы. Как и в следующем коде, Logger установит значение nullLogger, если класс еще не настроен, но когда Resolve закончен, будет установлено свойство Logger.

private ILogger logger;

public ILogger Logger
{
    get
    {
        if (logger == null) 
            logger = NullLogger.Instance;
        return logger;
    }
    set { logger = value; }
}

Так что мне интересно, как и где Windsor устанавливает свойство Logger.

Приветствия Энтони

Ответ 1

Регистратор настраивается средством ведения журнала, который находится в разделе <facilities> конфигурации. Например, для использования log4net ваше приложение или web.config будет выглядеть примерно так:

<?xml version="1.0"?>
<configuration>
    <configSections>
        <section name="castle" type="Castle.Windsor.Configuration.AppDomain.CastleSectionHandler, Castle.Windsor"/>
    </configSections>
<Configuration>

<castle>

    <facilities>
        <facility id="loggingfacility" 
             type="Castle.Facilities.Logging.LoggingFacility, Castle.Facilities.Logging" 
             loggingApi="log4net" 
             configFile="logging.config" />
    </facilities>

</castle>
</configuration>

Ответ 2

Вы также можете настроить эту программу при инициализации Windsor (например, с вашего global.asax.cs):

container.AddFacility("logging",  new LoggingFacility(LoggerImplementation.Log4net));

Разумеется, вы можете выбрать любую из задач логгера.

Это будет подключаться, когда Windsor создает экземпляр любого класса, ожидающего регистратора. Я бы не поставил это в конструкторе, поскольку это перекрестная озабоченность - лучше поступить так, как вы предложили, на мой взгляд. Вы можете немного упростить его:

    private ILogger logger = NullLogger.Instance;
    public ILogger Logger
    {
        get { return logger; }
        set { logger = value; }
    }

Ответ 3

Поскольку у вас есть общедоступное свойство с сеттером, каждый раз, когда вы разрешаете свой объект из Windsor, он также пытается установить любые общедоступные свойства с соответствующими значениями из контейнера (в вашем случае, ILogger, который ваш объект будет заселен в Виндзор).

Значение, если вы разрешите Class от Windsor, это будет установлено. Но нет, если вы создадите новый класс().

По крайней мере, как я это понимаю.

Другой подход заключается в использовании конструкторов, то есть, если у вас есть конструктор с именем

public Class (регистратор ILogger) он будет создан с помощью ILogger в качестве параметра.

Пример:

var yourClassObject = Kernel.Resolve<IClass>();

ЕСЛИ у вас нет спецификации интерфейса (и зарегистрировано как таковая), вам нужно будет зарегистрировать ваш компонент как конкретный тип, если вы хотите его решить, используя этот конкретный тип (а не по интерфейсу).