如果不向类本身插入某种代码或在类周围创建Factory 来管理实例化,则无法拦截正在创建的对象。
假设你有这样的课程:
public class MyData
{
[Captialization]
public string Name { get; set; }
}
使用如下定义的属性:
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Class)]
public class CaptializationAttribute : Attribute { }
您可以检测和操作标记有各种属性的属性,如下所示:
public static class DataUtilities
{
public static void ApplyAttributes<T>(T obj)
{
// Capitalization attribute
var props = typeof (T).GetProperties().Where(p => p.GetCustomAttributes(typeof (CaptializationAttribute), true).Any());
foreach (var prop in props)
{
// This is just an example, if you use this code you
// should check if the property is a string first!
prop.SetValue(obj, prop.GetValue(obj).ToString().ToUpper());
// Or perform some other manipulation here.
}
}
}
现在,要自动调用此代码,您需要决定何时发生。如果它在实例化之后很好,你可能不得不从某个地方自己调用它。但如果是在实例化期间,您可以执行以下两种操作之一:
使用工厂:
public static class MyDataFactory
{
public static MyData Create()
{
var myData = new MyData();
DataUtilities.ApplyAttributes(myData);
return myData;
}
}
您可能希望使用内部构造函数来防止外部实例化。
// No instantiation from outside the assembly
internal MyData() { }
使用构造函数:
将操作实用程序的调用添加到您的构造函数中:
public MyData()
{
DataUtilities.ApplyAttributes(this);
}
还有其他方法可以做到这一点,例如使用Proxy、Dependency Injection,或@Yuval Itzchakov 提到的AOP framework,但我描述的那些可能是最容易实现的。