技术开发 频道

用.NET实现AOP框架


C# 定义具体装饰属性

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
class ArgumentTypeRestrictionAttribute : DecoratorAttributeBase
{
private Type type;
public ArgumentTypeRestrictionAttribute(Type type) { this.type = type; }
public override void Intercept(object target)
{
MethodCallMessageWrapper caller = (MethodCallMessageWrapper)target;
if (caller.ArgCount == 0) return;
for (int i = 0; i < caller.ArgCount; i++)
{
object arg = caller.Args[i];
if ((arg.GetType() != type) && (!arg.GetType().IsAssignableFrom(type)))
throw new ArgumentException(i.ToString());
}
}
}

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
class ArgumentNotEmptyAttribute : DecoratorAttributeBase
{
public override void Intercept(object target)
{
MethodCallMessageWrapper caller = (MethodCallMessageWrapper)target;
if(caller.ArgCount == 0) return;
foreach(object arg in caller.Args)
if(string.IsNullOrEmpty((string)arg))
throw new ArgumentException();
}
}
C# 定义业务对象
class User : MarshalByRefObject 
{
private string name;
private string title;

[ArgumentTypeRestriction(typeof(string))] // 提供拦截入口
[ArgumentNotEmpty()] // 提供拦截入口
public void SetUserInfo(object name, object title)
{
this.name = (string)name;
this.title = (string)title;
}
}
Unit Test
[TestMethod] 
public void Test()
{
User user = CustomProxy<User>.Create(new User());
user.SetUserInfo("joe", "manager"); // 成功
try
{
user.SetUserInfo(20, "manager");
}
catch (Exception exception)
{
// 因第一个参数类型异常被拦截后抛出异常
Assert.AreEqual<string>("0", exception.Message);
}
try
{
user.SetUserInfo("", "manager");
}
catch (Exception exception)
{
// 因name为空被拦截后抛出异常
Assert.AreEqual<string>("string is null or empty", exception.Message);
}
}
0
相关文章