我在我的项目上实现了存储库装饰模式:
[Auditable]
public class Product
{
public int Id {get; set;}
public string Name {get; set;}
}
我从以下链接中得到了这个想法。
https://efpatterns.codeplex.com/discussions/282699
但无法成功实施。然后我开始学习装饰器模式和DataAnnotation,因为Product实体上的Auditable属性在DataAnnotation和装饰器模式中有些类似。所以我的问题是他们是一回事。如果它们是相同的,那么我将如何在我的项目中实现Auditable存储库模式(更多链接)。
答案 0 :(得分:0)
装饰器模式是一种将给定接口的基本实现扩展其行为而不修改原始实现的机制。
它的类似继承自基类,但它具有更大的灵活性。例如,装饰器类可以应用于实现相同接口的任何其他类,没有限制只扩展单个基类。它们也可以链接在一起等......
e.g
public interface IThing
{
void AMethod()
}
public abstract class ThingDecorator : IThing
{
private IThing inner;
public ThingDecorator(IThing inner)
{
this.inner = inner;
}
public virtual void AMethod()
{
this.inner.AMethod();
}
}
继承ThingDecorator并将自己的扩展应用于虚拟AMethod将添加行为(装饰)传入的内部实例。由于内部实例耦合到接口,因此它可以是该接口的任何实现。
在您的示例中,您可以将ThingDecorator作为AuditThingDecorator继承,并在调用base之前覆盖AMethod并包含Audit功能.AMethod()
这与仅将属性应用于类不同。我认为您正在尝试使用属性应用行为。如果存在容器,或者系统的某些其他部分可以读取它们并实际应用给定行为,则属性只能将行为应用于类。使用DataAnnotations,还有其他类可以读取这些属性并应用行为(例如,在ASP.NET MVC中,DefaultModelBinder使用一些属性在绑定模型时提供验证)。
这是一种AOP(面向对象编程)方法。应用此方法(以及我倾向于使用的方法)的一种方法是使用Castle.Core并创建拦截器,这些拦截器可以自动实现接口方法或扩展虚拟方法并从拦截的方法/属性中读取属性,然后应用行为:
http://docs.castleproject.org/Tools.DynamicProxy-Introduction.ashx
它们本质上都是给定类型的代理,但上面的Decorator模式不是动态的,它们是在代码中创建的,AOP方法可以在运行时应用行为。
答案 1 :(得分:0)
这不是最初由Gang Of Four描述的decorator pattern。
装饰器模式是一种向现有类添加功能的继承技术。该模式通过创建一组子类来工作,每个子类在基类之上提供特定类型的功能。
然后通过将现有实例作为内部对象传递给子类实例来组合组合:
public class SecurityToken
public class ExpiringToken : SecurityToken;
public class RpcSecurityToken : SecurityToken;
因此,如果您想拥有一个远程令牌,并且会在一段时间后过期:
var token = new RpcSecurityToken(new ExpiringToken(new SecurityToken("sds")));
你所做的只是用一个属性装饰一个类,这不是一回事。