XDecorator是一个开源的面向接口的动态装饰系统。装饰的类型和被装饰的类型必须是一个公开的接口,具体部分需要一个具体的混入类来控制。
看一下基本使用:
1、一个被装饰的接口(INamedObject)
public
interface
INamedObject
... {
string Name ...{ get; set; }
}
... {
string Name ...{ get; set; }
}
2、一个装饰后的接口(INamedObjectEx)
public
interface
INamedObjectEx
: INamedObject
... {
event EventHandler NameChanged;
}
: INamedObject
... {
event EventHandler NameChanged;
}
3、一个混入类(NotifyMixin)
[DecoratorMixinType(
typeof
(INamedObject),
typeof
(INamedObjectEx))]
public class NotifyMixin
... {
private INamedObject _src;
private INamedObjectEx _decorator;
public NotifyMixin(INamedObject src, INamedObjectEx decorator)
...{
_src = src;
_decorator = decorator;
}
[DecoratorMixinProperty()]
public string Name
...{
get ...{ return _src.Name; }
set
...{
if (value != _src.Name)
...{
_src.Name = value;
OnNameChanged(EventArgs.Empty);
}
}
}
protected virtual void OnNameChanged(EventArgs e)
...{
if (NameChanged != null)
NameChanged(_decorator, e);
}
[DecoratorMixinEvent()]
public event EventHandler NameChanged;
}
public class NotifyMixin
... {
private INamedObject _src;
private INamedObjectEx _decorator;
public NotifyMixin(INamedObject src, INamedObjectEx decorator)
...{
_src = src;
_decorator = decorator;
}
[DecoratorMixinProperty()]
public string Name
...{
get ...{ return _src.Name; }
set
...{
if (value != _src.Name)
...{
_src.Name = value;
OnNameChanged(EventArgs.Empty);
}
}
}
protected virtual void OnNameChanged(EventArgs e)
...{
if (NameChanged != null)
NameChanged(_decorator, e);
}
[DecoratorMixinEvent()]
public event EventHandler NameChanged;
}
所有的必须部分已经完成,为了让程序能够跑起来,额外需要一个INamedObject的具体实现类(如果对动态接口概念熟悉的话,也可以用动态接口来获得实例)
public
sealed
class
SomeNamedObject
: INamedObject
... {
Fields#region Fields
private string _name = "Anonymous";
#endregion
Ctors#region Ctors
public SomeNamedObject() ...{ }
#endregion
INamedObject Members#region INamedObject Members
public string Name
...{
get ...{ return _name; }
set ...{ _name = value; }
}
#endregion
}
: INamedObject
... {
Fields#region Fields
private string _name = "Anonymous";
#endregion
Ctors#region Ctors
public SomeNamedObject() ...{ }
#endregion
INamedObject Members#region INamedObject Members
public string Name
...{
get ...{ return _name; }
set ...{ _name = value; }
}
#endregion
}
现在就可以写主程序了,代码如下:
class
Program
... {
static void Main(string[] args)
...{
INamedObject obj = new SomeNamedObject();
INamedObjectEx decorator = DecoratorFactory.Create<INamedObject, INamedObjectEx, NotifyMixin>(obj);
Console.WriteLine("obj's name is: {0}", obj.Name);
decorator.NameChanged += new EventHandler(decorator_NameChanged);
decorator.Name = "new name";
Console.WriteLine("obj's name is: {0}", obj.Name);
Console.ReadLine();
}
static void decorator_NameChanged(object sender, EventArgs e)
...{
INamedObjectEx decorator = sender as INamedObjectEx;
Console.WriteLine("name changed to: {0}", decorator.Name);
}
}
... {
static void Main(string[] args)
...{
INamedObject obj = new SomeNamedObject();
INamedObjectEx decorator = DecoratorFactory.Create<INamedObject, INamedObjectEx, NotifyMixin>(obj);
Console.WriteLine("obj's name is: {0}", obj.Name);
decorator.NameChanged += new EventHandler(decorator_NameChanged);
decorator.Name = "new name";
Console.WriteLine("obj's name is: {0}", obj.Name);
Console.ReadLine();
}
static void decorator_NameChanged(object sender, EventArgs e)
...{
INamedObjectEx decorator = sender as INamedObjectEx;
Console.WriteLine("name changed to: {0}", decorator.Name);
}
}
这里将一个INamedObject的实例包装成一个INamedObjectEx的实例,访问其中改写过的Name属性和新增加的NameChanged事件。
XDecorator下载请到本人的下载资源中下载(包含程序集和源代码)