Tak jsem se stal obětí moderních programovacích technik, konkrétně aspektově orientovaného programování, o kterém jsem blogoval posledně.
Pro business třídy jsem si udělal nádherný aspekt, který zajišťuje, že před každou odekorovanou metodou je ověřeno, jestli je vytvořen objekt pro připojení k databázi (automatic property Context). Takže jsem si pak pěkně každou metodu business objektu, která používá tuto property Context, odekoroval aspektem RequiresContext. Všechno krásně fungovalo a já si bušil do hrudi, jak jsem pěkně využil AOP. No ale když jsem se pak s tím jen tak mimochodem chlubil na IRC, tak měl posila dobrou připomínku – co udělat test na vytvoření Contextu v getteru této property? 🙂 Tak jsem milý aspekt smazal (ale mohlo mi to srdce utrhnout) a napchal test do getteru (kde jsem využil operátor ?? – znáte ho? 😉 )
Pro úplnost kód před:
public abstract class CustomBusinessObject : IDisposable
{
public DBContext Context
{
get;
set;
}
public void Dispose()
{
DBContext c = this.Context;
if (c != null)
{
try
{
c.Dispose();
}
finally
{
this.Context = null;
}
}
}
[ContextRequired]
public void SomeMethod()
{
// some work with Context
}
}
public class ContextRequiredAttribute : PostSharp.Laos.OnMethodBoundaryAspect
{
public override bool CompileTimeValidate(System.Reflection.MethodBase method)
{
return typeof(CustomBusinessObject).IsAssignableFrom(method.DeclaringType);
}
public override void OnEntry(PostSharp.Laos.MethodExecutionEventArgs eventArgs)
{
var i = eventArgs.Instance as CustomBusinessObject;
if (i != null && i.Context == null)
{
i.Context = new DBContext();
}
}
}
A kód po zásahu:
public abstract class CustomBusinessObject : IDisposable
{
public DBContext Context
{
get { return this.mContext ?? (this.mContext = new DBContext()); }
}
protected DBContext mContext;
public void Dispose()
{
DBContext c = this.mContext;
if (c != null)
{
try
{
c.Dispose();
}
finally
{
this.mContext = null;
}
}
}
public void SomeMethod()
{
// some work with Context
}
}
Co takhle zase jednou post srozumitelny i pro nas obycejny chudaky?
To se mi líbíTo se mi líbí
Chtel jsem se zasmat, ale… WTF?!
To se mi líbíTo se mi líbí
Pomalu jsem se začínal stydět, že mi po 6ti letech dali diplom a tohle vůbec nedávám… Díky AlenKo a Vojto, že jste to tak pěkně okomentovali. Alespoň prozatím diplom vrátit nepůjdu…
To se mi líbíTo se mi líbí
Ee, operator ?? sme nepoznali, ale uz pozname. Skoda, ze C+ nema 🙂 Takze po zasahu sa z toho AOP stratilo?
Jo a btw, pred zasahom: mas tam identifikator „ContextRequired“, ten sa niekde asi zadefinuje, ze? Ja vidim len „ContextRequiredAttribute“…
To se mi líbíTo se mi líbí
Jo, AOP jsem odstranil, protože tady bylo kontraproduktivní – prostě jsem to překombinoval a nechal se unést 😉
Když máš nějaký atribut (tzn. třídu poděděnou od System.Attribute), tak pokud název třídy končí na „Attribute“, tak pak při aplikaci tohodle atributu můžeš tenhle sufix vynechat – pokud to teda nevede na nějaký nejednoznačnosti apod.
Jo a AOP jde použít snad ve všech jazycích – ohledně C++ čekuj třeba http://www.aspectc.org 🙂 O operátoru ?? v C++ jsem neslyšel, ale bůhví co přinese C++0x 🙂
To se mi líbíTo se mi líbí