Лучше всего регистрируя подход для составного приложения?

Для массивов используйте минус оператор. Например:

>> foo = [1, 2, 3]
=> [1, 2, 3]
>> goo = [2, 3, 4]
=> [2, 3, 4]
>> foo - goo
=> [1]

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

15
задан Metro Smurf 15 February 2011 в 20:22
поделиться

3 ответа

Простейший подход к регистрации в Prism - переопределить свойство LoggerFacade в вашем Bootstrapper . Переопределив LoggerFacade , вы можете передать экземпляр любого регистратора, который хотите, с любой необходимой конфигурацией, если регистратор реализует интерфейс ILoggerFacade .

Я нашел следующее, чтобы хорошо работать для ведения журнала (я использую блок Enterprise Libary Logging, но применение чего-то похожего для Log4Net должно быть прямым):

Создайте Boostrapper в своей оболочке:

-My Project
  -Shell Module (add a reference to the Infrastructure project)
    -Bootstrapper.cs

Создайте адаптер ведения журнала в вашей инфраструктуре проект, например:

-My Project
  -Infrastructure Module
    -Adapters
      -Logging
        -MyCustomLoggerAdapter.cs
        -MyCustomLoggerAdapterExtendedAdapter.cs
        -IFormalLogger.cs

Класс MyCustomLoggerAdapter будет использоваться для переопределения свойства LoggerFacade в загрузчике. У него должен быть конструктор по умолчанию, который сообщает все новости.

Примечание: переопределив свойство LoggerFacade в Bootstrapper, вы предоставляете Prism механизм регистрации, который будет использовать для регистрации собственных внутренних сообщений. Вы можете использовать этот регистратор во всем своем приложении или можете расширить регистратор для более полнофункционального регистратора. (см. MyCustomLoggerAdapterExtendedAdapter / IFormalLogger )

public class MyCustomLoggerAdapter : ILoggerFacade
{

    #region ILoggerFacade Members

    /// <summary>
    /// Logs an entry using the Enterprise Library logging. 
    /// For logging a Category.Exception type, it is preferred to use
    /// the EnterpriseLibraryLoggerAdapter.Exception methods."
    /// </summary>
    public void Log( string message, Category category, Priority priority )
    {
        if( category == Category.Exception )
        {
            Exception( new Exception( message ), ExceptionPolicies.Default );
            return;
        }

        Logger.Write( message, category.ToString(), ( int )priority );
    }

    #endregion


    /// <summary>
    /// Logs an entry using the Enterprise Library Logging.
    /// </summary>
    /// <param name="entry">the LogEntry object used to log the 
    /// entry with Enterprise Library.</param>
    public void Log( LogEntry entry )
    {
        Logger.Write( entry );
    }

    // Other methods if needed, i.e., a default Exception logger.
    public void Exception ( Exception ex ) { // do stuff }
}

MyCustomLoggerAdapterExtendedAdapter получен из полного конструктора MyCustomLog 1155404- MyCustomLog для дополнительных возможностей. fledged logger.

public class MyCustomLoggerAdapterExtendedAdapter : MyCustomLoggerAdapter, IFormalLogger
{

    private readonly ILoggingPolicySection _config;
    private LogEntry _infoPolicy;
    private LogEntry _debugPolicy;
    private LogEntry _warnPolicy;
    private LogEntry _errorPolicy;

    private LogEntry InfoLog
    {
        get
        {
            if( _infoPolicy == null )
            {
                LogEntry log = GetLogEntryByPolicyName( LogPolicies.Info );
                _infoPolicy = log;
            }
            return _infoPolicy;
        }
    }

    // removed backing code for brevity
    private LogEntry DebugLog... WarnLog... ErrorLog


    // ILoggingPolicySection is passed via constructor injection in the bootstrapper
    // and is used to configure various logging policies.
    public MyCustomLoggerAdapterExtendedAdapter ( ILoggingPolicySection loggingPolicySection )
    {
        _config = loggingPolicySection;
    }


    #region IFormalLogger Members

    /// <summary>
    /// Info: informational statements concerning program state, 
    /// representing program events or behavior tracking.
    /// </summary>
    /// <param name="message"></param>
    public void Info( string message )
    {
        InfoLog.Message = message;
        InfoLog.ExtendedProperties.Clear();
        base.Log( InfoLog );
    }

    /// <summary>
    /// Debug: fine-grained statements concerning program state, 
    /// typically used for debugging.
    /// </summary>
    /// <param name="message"></param>
    public void Debug( string message )
    {
        DebugLog.Message = message;
        DebugLog.ExtendedProperties.Clear();
        base.Log( DebugLog );
    }

    /// <summary>
    /// Warn: statements that describe potentially harmful 
    /// events or states in the program.
    /// </summary>
    /// <param name="message"></param>
    public void Warn( string message )
    {
        WarnLog.Message = message;
        WarnLog.ExtendedProperties.Clear();
        base.Log( WarnLog );
    }

    /// <summary>
    /// Error: statements that describe non-fatal errors in the application; 
    /// sometimes used for handled exceptions. For more defined Exception
    /// logging, use the Exception method in this class.
    /// </summary>
    /// <param name="message"></param>
    public void Error( string message )
    {
        ErrorLog.Message = message;
        ErrorLog.ExtendedProperties.Clear();
        base.Log( ErrorLog );
    }

    /// <summary>
    /// Logs an Exception using the Default EntLib Exception policy
    /// as defined in the Exceptions.config file.
    /// </summary>
    /// <param name="ex"></param>
    public void Exception( Exception ex )
    {
        base.Exception( ex, ExceptionPolicies.Default );
    }

    #endregion


    /// <summary>
    /// Creates a LogEntry object based on the policy name as 
    /// defined in the logging config file.
    /// </summary>
    /// <param name="policyName">name of the policy to get.</param>
    /// <returns>a new LogEntry object.</returns>
    private LogEntry GetLogEntryByPolicyName( string policyName )
    {
        if( !_config.Policies.Contains( policyName ) )
        {
            throw new ArgumentException( string.Format(
              "The policy '{0}' does not exist in the LoggingPoliciesCollection", 
              policyName ) );
        }

        ILoggingPolicyElement policy = _config.Policies[policyName];

        var log = new LogEntry();
        log.Categories.Add( policy.Category );
        log.Title = policy.Title;
        log.EventId = policy.EventId;
        log.Severity = policy.Severity;
        log.Priority = ( int )policy.Priority;
        log.ExtendedProperties.Clear();

        return log;
    }

}


public interface IFormalLogger
{

    void Info( string message );

    void Debug( string message );

    void Warn( string message );

    void Error( string message );

    void Exception( Exception ex );

}

В Bootstrapper :

public class MyProjectBootstrapper : UnityBootstrapper
{

  protected override void ConfigureContainer()
  {
    // ... arbitrary stuff

    // create constructor injection for the MyCustomLoggerAdapterExtendedAdapter
      var logPolicyConfigSection = ConfigurationManager.GetSection( LogPolicies.CorporateLoggingConfiguration );
      var injectedLogPolicy = new InjectionConstructor( logPolicyConfigSection as LoggingPolicySection );

      // register the MyCustomLoggerAdapterExtendedAdapter
      Container.RegisterType<IFormalLogger, MyCustomLoggerAdapterExtendedAdapter>(
              new ContainerControlledLifetimeManager(), injectedLogPolicy );

  }

    private readonly MyCustomLoggerAdapter _logger = new MyCustomLoggerAdapter();
    protected override ILoggerFacade LoggerFacade
    {
        get
        {
            return _logger;
        }
    }

}

Наконец, чтобы использовать любой регистратор, все, что вам нужно сделать, это добавить соответствующий интерфейс к вашему классу ' конструктор, и UnityContainer внедрит регистратор за вас:

public partial class Shell : Window, IShellView
{
    private readonly IFormalLogger _logger;
    private readonly ILoggerFacade _loggerFacade;

    public Shell( IFormalLogger logger, ILoggerFacade loggerFacade )
    {
        _logger = logger;
        _loggerFacade = loggerFacade

        _logger.Debug( "Shell: Instantiating the .ctor." );
        _loggerFacade.Log( "My Message", Category.Debug, Priority.None );

        InitializeComponent();
    }


    #region IShellView Members

    public void ShowView()
    {
        _logger.Debug( "Shell: Showing the Shell (ShowView)." );
         _loggerFacade.Log( "Shell: Showing the Shell (ShowView).", Category.Debug, Priority.None );
       this.Show();
    }

    #endregion

}

Я не думаю, что вам нужен отдельный модуль для политики ведения журнала. При добавлении политик ведения журнала к вашему модулю инфраструктуры все остальные модули получат необходимые ссылки (при условии, что вы добавляете модуль инфраструктуры в качестве ссылки на другие модули). А добавив регистратор к вашему Boostrapper, вы можете позволить UnityContainer внедрить политику ведения журнала по мере необходимости.

Существует простой пример использования Log4Net в проекте CompositeWPF contrib на CodePlex.

] HTH

все остальные модули получат необходимые ссылки (при условии, что вы добавляете модуль инфраструктуры в качестве ссылки на другие модули). А добавив регистратор к вашему Boostrapper, вы можете позволить UnityContainer внедрить политику ведения журнала по мере необходимости.

Существует простой пример использования Log4Net в проекте CompositeWPF contrib на CodePlex.

] HTH

все остальные модули получат необходимые ссылки (при условии, что вы добавляете модуль инфраструктуры в качестве ссылки на другие модули). А добавив регистратор к вашему Boostrapper, вы можете позволить UnityContainer внедрить политику ведения журнала по мере необходимости.

Существует простой пример использования Log4Net в проекте CompositeWPF contrib на CodePlex.

] HTH

18
ответ дан 1 December 2019 в 02:37
поделиться

Наличие отдельных конфигураций регистратора для каждого модуля может привести к проблемам при развертывании. Помните, что опытный пользователь или администратор может полностью изменить цель вашей регистрации, перенаправив ее в базу данных или в службу агрегированной регистрации в центральном репозитории (например, моя компания ). Если все отдельные модули имеют разные конфигурации, опытный пользователь / администратор должен повторить конфигурацию для каждого модуля (в каждом файле .config или в разделе каждого модуля в главном app.config) и повторять это каждый раз при изменении местоположения / происходит форматирование. Кроме того, учитывая, что приложения добавляются во время выполнения из конфигурации и могут быть приложения, о которых вы ничего не знаете в данный момент, кто-то может использовать приложение, которое блокирует файл и приводит к конфликту между модулями приложения. Использование одной единственной конфигурации log4.net упрощает администрирование.

Отдельные модули по-прежнему могут быть настроены в соответствии с потребностями каждого, отдельно (например, INFO для уровня БД, ERROR для уровня пользовательского интерфейса). Каждый модуль будет получать регистратор, запрашивая его собственный тип: LogManager.GetLogger (typeof (MyModule); , но только оболочка настраивает регистратор (например, вызывает XmlConfigurator.Configure), используя свое собственное приложение. конфигурация

1
ответ дан 1 December 2019 в 02:37
поделиться

Я наконец вернулся к этому, и оказалось, что ответ действительно довольно прост. В проекте Shell настройте Log4Net как пользовательский регистратор. Документация Prism (февраль 2009 г.) объясняет, как это сделать, на стр. 287). Проект Shell - единственный проект, которому нужна ссылка на Log4Net. Чтобы получить доступ к регистратору (при условии, что всем модулям передана ссылка на контейнер Prism IOC), просто разрешите ILoggerFacade в контейнере IOC, который даст вам ссылку на ваш пользовательский регистратор. Передайте сообщение этому регистратору обычным образом.

Таким образом, нет необходимости в возврате событий в оболочку и нет необходимости в модулях иметь ссылки на Log4Net. Святая скумбрия, я люблю контейнеры МОК!

4
ответ дан 1 December 2019 в 02:37
поделиться
Другие вопросы по тегам:

Похожие вопросы: