using System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using PostSharp.Laos; namespace MyNamespace { /// /// Must be applied to a method if the NotNullAttribute attribute is on a parameter /// This is temporary until PostSharp gets a OnParameterBoundaryAspect /// [Serializable] [AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor, AllowMultiple = false)] public class NotNullHelperAttribute : OnMethodBoundaryAspect { private IList _mapping; private bool _applyToAll = false; /// /// If set to true, all parameters of the method are required to be not null /// public bool ApplyToAll { get { return _applyToAll; } set { _applyToAll = value; } } public override void RuntimeInitialize(MethodBase method) { base.RuntimeInitialize(method); ParameterInfo[] pinfo = method.GetParameters(); _mapping = new List(); foreach (ParameterInfo info in pinfo) { NotNullAttribute attrib = (NotNullAttribute)GetCustomAttribute(info, typeof(NotNullAttribute)); if (_applyToAll) _mapping.Add(new ParamInfo(info, string.Empty)); else if (attrib != null) _mapping.Add(new ParamInfo(info, attrib.Message)); else _mapping.Add(null); } } [DebuggerStepThrough] public override void OnEntry(MethodExecutionEventArgs eventArgs) { object[] args = eventArgs.GetArguments(); for (int i = 0; i < args.Length; ++i) { if (_mapping[i] != null) { if (args[i] == null || (_mapping[i].ParameterType == typeof(string) && string.IsNullOrEmpty((string)args[i]))) throw new ArgumentNullException(_mapping[i].Name, _mapping[i].Message); } } } #region Nested type: ParamInfo [Serializable] private class ParamInfo { public readonly string Message; public readonly string Name; public readonly Type ParameterType; public ParamInfo(ParameterInfo pinfo, string message) { ParameterType = pinfo.ParameterType; Name = pinfo.Name; Message = message; } } #endregion } /// /// Throws an error for all parameters its applied to *if* the parameter is null, or if a string and is empty /// [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)] internal class NotNullAttribute : Attribute { public string Message; public NotNullAttribute() { } public NotNullAttribute(string message) { Message = message; } } }