2010-04-15 20 views
5

Metot, bir yöntem ya da herhangi bir yönteme eklenecek bir sınıf yazmanın bir yolu olup olmadığını, birçok yöntem arasında paylaşılan bir kod olup olmadığını merak ediyorum. Yöntemler farklı şeyler döndürür ve bazıları sadece boştur.Kod çoğaltmasını önlemek için başkaları ile başa çıkmak için bir yöntem kullanmanın bir yolu var mı?

Aşağıda, yöntemlerde çoğaltılan kodun bir kısmı yer almaktadır.

StartTimer(MethodBase.GetCurrentMethod().Name); 
try 
{ 
    // Actual method body 
} 
catch (Exception ex) 
{ 
    bool rethrow = ExceptionPolicy.HandleException(ex, "DALPolicy"); 
    if (rethrow) 
    { 
     throw; 
    } 
} 
finally 
{ 
    StopTimer(MethodBase.GetCurrentMethod().Name); 
} 

Herhangi bir yardım çok takdir edilecektir.


Nix çözüm

public T WrapMethod<T>(Func<T> func) 
{ 
    StartTimer(func.Method.Name); 
    try 
    { 
     return func(); 
    } 
    catch (Exception ex) 
    { 
     bool rethrow = ExceptionPolicy.HandleException(ex, "DALPolicy"); 
     if (rethrow) 
     { 
      throw; 
     } 
    } 
    finally 
    { 
     StopTimer(func.Method.Name); 
    } 
    return default(T); 
} 

cevap

5
Yukarıdaki kod uygulanan

Aslında bu aynı sorunu ....

C# searching for new Tool for the tool box, how to template this code

public Result<Boolean> CreateLocation(LocationKey key) 
{ 
    LocationDAO locationDAO = new LocationDAO(); 
    return WrapMethod(() => locationDAO.CreateLocation(key)); 
} 


public Result<Boolean> RemoveLocation(LocationKey key) 
{ 
    LocationDAO locationDAO = new LocationDAO(); 
    return WrapMethod(() => locationDAO.RemoveLocation(key)); 
} 


static Result<T> WrapMethod<T>(Func<Result<T>> func) 
{ 
    try 
    { 
     return func(); 
    } 
    catch (UpdateException ue) 
    { 
     return new Result<T>(default(T), ue.Errors); 
    } 
} 
2

genellikle Aspect ile gerçekleştirilir oluyor vardı Yönlendirilmiş Programlama ve bildiğim kadarıyla Şu anda bu özellik için .NET çerçevesinde (veya C#) destek yok. Bakınız this post.

bildiğim kadarıyla kavramak olabilir olarak da

, - yaptıktan olmadan herhangi kendim test - zaman o da düşünebilirsiniz böylece AOP ContextBoundObject sınıfa dayalı .NET özelliklerinizi sağlamak frameworks performans yükü bir sürü tabi görünüyor Kullanım kolaylığı avantajının performanstaki dezavantajdan daha büyük olup olmadığına karar vermek.

+0

Yeh, ben AOP'nin düşünmüştüm fakat bazen bazı için kullanmak başlamak için korkutucu oluşudur. C# A http://csharp-source.net/open-source/aspect-oriented-frameworks – AaronLS

1

Sarılacak kodu iletmek için delegeleri ve public delegate T Func<T>(); gibi genel delegeleri kullanabilirsiniz. Aşağıdaki örnekte, yeniden deneme mantığımın birçok senaryoda yeniden kullanılmasını istediğim yere benzer bir şeye ihtiyacım vardı. başında örnekte bu benim anonim delege geçmek için nasıl kullanıldığını bakın:

public class RetryOnError 
{ 
    static void Example() 
    { 
     string endOfLineChar = Environment.NewLine; 
     RetryOnError.RetryUntil<string>(delegate() 
     { 
      //attempt some potentially error throwing operations here 

      //you can access local variables declared outside the the Retry block: 
      return "some data after successful processing" + endOfLineChar; 
     }, 
     new RetryOnError.OnException(delegate(ref Exception ex, ref bool rethrow) 
     { 
      //respond to the error and 
      //do some analysis to determine if a retry should occur 
      //perhaps prompting the user to correct a problem with a retry dialog 
      bool shouldRetry = false; 

      //maybe log error 
      log4net.Error(ex); 

      //maybe you want to wrap the Exception for some reason 
      ex = new Exception("An unrecoverable failure occurred.", ex); 
      rethrow = true;//maybe reset stack trace 

      return shouldRetry;//stop retrying, normally done conditionally instead 
     })); 
    } 

    /// <summary> 
    /// A delegate that returns type T 
    /// </summary> 
    /// <typeparam name="T">The type to be returned.</typeparam> 
    /// <returns></returns> 
    public delegate T Func<T>(); 

    /// <summary> 
    /// An exception handler that returns false if Exception should be propogated 
    /// or true if it should be ignored. 
    /// </summary> 
    /// <returns>A indicater of whether an exception should be ignored(true) or propogated(false).</returns> 
    public delegate bool OnException(ref Exception ex, ref bool rethrow); 

    /// <summary> 
    /// Repeatedly executes retryThis until it executes successfully with 
    /// an exception, maxTries is reached, or onException returns false. 
    /// If retryThis is succesful, then its return value is returned by RetryUntil. 
    /// </summary> 
    /// <typeparam name="T">The type returned by retryThis, and subsequently returned by RetryUntil</typeparam> 
    /// <param name="retryThis">The delegate to be called until success or until break condition.</param> 
    /// <param name="onException">Exception handler that can be implemented to perform logging, 
    /// notify user, and indicates whether retrying should continue. Return of true indicates 
    /// ignore exception and continue execution, and false indicates break retrying and the 
    /// exception will be propogated.</param> 
    /// <param name="maxTries">Once retryThis has been called unsuccessfully <c>maxTries</c> times, then the exception is propagated. 
    /// If maxTries is zero, then it will retry forever until success. 
    /// </param> 
    /// <returns>The value returned by retryThis on successful execution.</returns> 
    public static T RetryUntil<T>(Func<T> retryThis, OnException onException, int maxTries) 
    { 
    //loop will run until either no exception occurs, or an exception is propogated(see catch block) 
    int i = 0; 
    while(true) 
    { 
     try 
     { 
     return retryThis(); 
     } 
     catch (Exception ex) 
     { 
     bool rethrow =false;//by default don't rethrow, just throw; to preserve stack trace 
     if ((i + 1) == maxTries) 
     {//if on last try, propogate exception 
      throw; 
     } 
     else if (onException(ref ex, ref rethrow)) 
     { 
      if (maxTries != 0) 
      {//if not infinite retries 
      ++i; 
      } 
      continue;//ignore exception and continue 
     } 
     else 
     { 
      if (rethrow) 
      { 
      throw ex;//propogate exception 
      } 
      else 
      {//else preserve stack trace 
      throw; 
      } 
     } 
     } 
    } 
    } 

    /// <summary> 
    /// Repeatedly executes retryThis until it executes successfully with 
    /// an exception, or onException returns false. 
    /// If retryThis is succesful, then its return value is returned by RetryUntil. 
    /// This function will run infinitly until success or onException returns false. 
    /// </summary> 
    /// <typeparam name="T">The type returned by retryThis, and subsequently returned by RetryUntil</typeparam> 
    /// <param name="retryThis">The delegate to be called until success or until break condition.</param> 
    /// <param name="onException">Exception handler that can be implemented to perform logging, 
    /// notify user, and indicates whether retrying should continue. Return of true indicates 
    /// ignore exception and continue execution, and false indicates break retrying and the 
    /// exception will be propogated.</param> 
    /// <returns></returns> 
    public static T RetryUntil<T>(Func<T> retryThis, OnException onException) 
    { 
    return RetryUntil<T>(retryThis, onException, 0); 
    } 
} 
+0

+1'deki AOP için bazı açık kaynak çerçeveleri, güzel örnek (kendi başına ilginç bir desen) –

İlgili konular