/// <summary>
 /// Initializes a new instance of the <see cref="LoggerAttribute"/> with an explicit logger name and <see cref="LoggerNamePolicy"/> for
 /// any generic arguments of the class.
 /// </summary>
 /// <param name="name">The name of <see cref="ILog"/>.</param>
 /// <param name="genericArgsNamePolicy">The <see cref="LoggerNamePolicy"/> to be used for any generic argument.</param>
 /// <remarks>
 /// The <paramref name="genericArgsNamePolicy"/> is a fall back policy. If any of the generic arguments types
 /// owns its own <see cref="LoggerAttribute"/> it will be used.
 /// </remarks>
 public LoggerAttribute(string name, LoggerNamePolicy genericArgsNamePolicy)
     : this(name)
 {
     m_genericArgsNamePolicy = genericArgsNamePolicy;
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="LoggerAttribute"/> with <see cref="LoggerNamePolicy"/> for
 /// the type and any generic arguments.
 /// </summary>
 /// <param name="namePolicy">The <see cref="LoggerNamePolicy"/> to be used for the type.</param>
 /// <param name="genericArgsNamePolicy">The <see cref="LoggerNamePolicy"/> to be used for any generic argument.</param>
 /// <remarks>
 /// The <paramref name="genericArgsNamePolicy"/> is a fall back policy. If any of the generic arguments types
 /// owns its own <see cref="LoggerAttribute"/> it will be used.
 /// </remarks>
 public LoggerAttribute(LoggerNamePolicy namePolicy, LoggerNamePolicy genericArgsNamePolicy)
 {
     m_namePolicy = namePolicy;
       m_genericArgsNamePolicy = genericArgsNamePolicy;
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="LoggerAttribute"/> with a <see cref="LoggerNamePolicy"/> for the class.
 /// </summary>
 /// <param name="namePolicy">The <see cref="LoggerNamePolicy"/> to be used.</param>
 public LoggerAttribute(LoggerNamePolicy namePolicy)
 {
     m_namePolicy = namePolicy;
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="LoggerAttribute"/> with an explicit logger name for the class.
 /// </summary>
 /// <param name="name">The name of <see cref="ILog"/>.</param>
 public LoggerAttribute(string name)
 {
     m_name = name;
       m_genericArgsNamePolicy = LoggerHelper.DefaultLoggerNamePolicy;
 }
        private static void GetLoggerName(Type type, Func<Type, LoggerAttribute> attFunc, LoggerNamePolicy fallbackPolicy, StringBuilder nameAccumulator)
        {
            LoggerAttribute log = attFunc(type);

              string loggerName = ApplyLoggerNamePolicy(type,
            log != null ? log.Name : string.Empty,
            log != null ? log.LoggerNamePolicy : fallbackPolicy);

              nameAccumulator.Append(loggerName);

              if (type.IsGenericType)
              {
            string delim = "<";
            LoggerNamePolicy genericArgsPolicy = log != null ? log.GenericArgsNamePolicy : fallbackPolicy;

            foreach (Type genericArg in type.GetGenericArguments())
            {
              //Check if the logger name for this type has already been registered.
              string gerericTypeName;
              if (sm_loggerNames.TryGetValue(genericArg, out gerericTypeName))
              {
            nameAccumulator.Append("<" + gerericTypeName + ">");
            return;
              }

              nameAccumulator.Append(delim);
              GetLoggerName(genericArg, (t) =>
                                    {
                                      LoggerAttribute[] atts = (LoggerAttribute[])t.GetCustomAttributes(typeof(LoggerAttribute), false);
                                      return atts.Length > 0 ? atts[0] : null;
                                    }
                                   , genericArgsPolicy, nameAccumulator);
              delim = ",";
            }

            nameAccumulator.Append(">");
              }
        }
        private static string ApplyLoggerNamePolicy(Type type, string customName, LoggerNamePolicy policy)
        {
            if (!string.IsNullOrEmpty(customName))
              {
            return customName;
              }

              switch (policy)
              {
              case LoggerNamePolicy.TypeName: return type.Name;
              case LoggerNamePolicy.FullTypeName: return type.FullName;
              case LoggerNamePolicy.AssemblyQualifiedName: return type.AssemblyQualifiedName;
              }

              Debug.Fail("Unsupported LoggerNamePolicy type");
              throw new ArgumentException("Unsupported LoggerNamePolicy type");
        }
        /// <summary>
        /// Generates a name for <see cref="ILog"/> for specific <see cref="Type"/> and registeres this name for this type's
        /// logger usage only. The name is generated according to the given logger name policies.
        /// </summary>
        /// <param name="type">The <see cref="Type"/> whose <see cref="ILog"/> name should be regsitered.</param>
        /// <param name="loggerNamePolicy">The <see cref="LoggerNamePolicy"/> to be applied on the name of the class.</param>
        /// <param name="genericArgsLoggerNamePolicy">The <see cref="LoggerNamePolicy"/> to be applied on the name of the generic arguments of class.</param>
        /// <returns>The name of the <see cref="ILog"/>.</returns>
        /// <remarks>
        /// If <paramref name="type"/> has a <see cref="LoggerAttribute"/> attached to it, the logic within the attribute will override 
        /// <paramref name="loggerNamePolicy"/> and <paramref name="genericArgsLoggerNamePolicy"/> parameters.
        /// </remarks>
        public static string RegisterLogger(Type type,
            LoggerNamePolicy loggerNamePolicy,
            LoggerNamePolicy genericArgsLoggerNamePolicy)
        {
            if (type == null)
              {
            Debug.Fail("type == null");
            throw new ArgumentNullException("type");
              }

              return RegisterLoggerInternal(type, (t) =>
            {
              LoggerAttribute[] atts = (LoggerAttribute[])t.GetCustomAttributes(typeof(LoggerAttribute), false);
              LoggerAttribute log = atts.Length > 0 ? atts[0] : null;

              //If the type contains its own LoggerAttribute, it will have the precedence.
              return log ?? new LoggerAttribute(loggerNamePolicy, genericArgsLoggerNamePolicy);
            });
        }