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
    }

} 
  • Facebook
  • TwitThis
  • LinkedIn
  • Live
  • Google Bookmarks
  • email