2013-01-09 13 views
10

Aşağıdaki bir durum var. Bazı .Net çalışma zamanı yöntemi çok iyi çalışmıyor ve bir geçici çözüm üretmem gerekiyor. Orada bazen kapalı bir okuyucu nesnesi döndüren SqlCommand.ExecuteReader() ve ona, bu gibi bir kod vardır istiyorum gibi: Şimdi artık çağırmasını sağlayacak şekilde ExecuteReader() çağıran tüm kodunu değiştirmek gerekir hariçC# yöntemini, başka bir adla aynı ad ve imza ile değiştirebilir miyim?

SqlDataReader MyExecuteReader(this SqlCommand command) 
{ 
    var reader = command.ExecuteReader(); 
    if(reader.IsClosed()) { 
     throw new ClosedReaderReturnedException(); 
    } 
    return reader; 
} 

Bu sadece iyi olurdu MyExecuteReader() ve Bakımı zorlaştırır.

Kodumdan herhangi biri MyExecuteReader() adı verilenistediğinde bunun yerine çağrılmasının bir yolu var mı? Mevcut bir yöntemi, aynı imzaya ve aynı ada sahip başka biriyle değiştirmek mümkün mü?

+12

bana kötü bir fikir gibi geliyor. – lahsrah

+0

O zaman bunun bir aşırı yük gibi görünmesi için bazı ekstra opsiyonel parametrelerle bir uzantısı yöntemi olabilir mi? Özür dilerim, cevap vermek yerine soru soruyorum. – shahkalpesh

+0

Muhtemelen profil api ya da gerçekten hacky ile bir şey. Burada birkaç yıl önce burada bir tane var http://www.codeproject.com/Articles/37549/CLR-Injection-Runtime-Method-Replacer buts gerçekten hacky – AbdElRaheim

cevap

9

Bu, aparat kullanarak ünite sınama kodunu denerken sorunlara benzer. o yuvarlak

bir yolu üzerinde ExecuteReader yöntemi ile bir arabirim uygulama bir nesne ile kod SqlCommand kullanımını değiştirmektir. Daha sonra nesneyi daha kolay bir şekilde değiştirebilirsiniz, belki bir fabrika modeli kullanarak.

Yani bunun gibi bir kod yerini alacak:

using (SqlCommand command = new SqlCommand(query)) 
{ 
    command.ExecuteReader(); 
} 

ile:

public interface ISqlCommand 
{ 
    SqlDataReader ExecuteReader(); 

    // further interface methods here... 
} 

Sonra oluşturmak:

var sqlCommandFactory = new SqlCommandFactory(); 
using (ISqlCommand command = sqlCommandFactory.CreateSqlCommand(query)) 
{ 
    command.ExecuteReader(); 
} 

Öncelikle yerine istediğiniz yöntemleri içeren arabirimi tanımlayan SqlCommand yapıcısı ile aynı imzayı kullanan bir fabrika:

internal class SqlCommandFactory 
{ 
    bool _useMyClass = true; 

    public ISqlCommand CreateSqlCommand(string query) 
    { 
     if (_useMyClass) 
     { 
      return new MySqlCommand(query); 
     } 
     else 
     { 
      return new SqlCommandWrapper(query); 
     } 
    } 
} 

Ardından MySqlCommand sınıfta yedek kod yazmak: .NET SqlCommand sınıf Açıkçası yeni ISqlCommand arabirimini uygulamıyor gibi

public MySqlCommand : ISqlCommand 
{ 
    public SqlDataReader ExecuteReader() 
    { 
     // your new code here 
    } 
} 

, bunu yapan bir sarmalayıcı sınıf oluşturmak:

public SqlCommandWrapper : ISqlCommand 
{ 
    SqlCommand _sqlCommand; 

    public SqlCommandWrapper(string query) 
    { 
     _sqlCommand = new SqlCommand(query); 
    } 

    public SqlDataReader ExecuteReader() 
    { 
     _sqlCommand.ExecuteReader(); 
    } 
} 

biraz ekstra çalışma, ancak bu yöntemin faydaları için uygulanmasını değişebileceğini ne olursa olsun sizi w ünite testi dahil olmak üzere karınca (bir sahte fabrikada kodunuza geçerek).

ekstra çalışma bir defalık olmalı ve istendiği gibi isim ve orijinal bir yöntem imzası korur olmalıdır. Bu kod siz (veya takım) bu tanınmış desen alışmakta kez özellikle (özel/uzatma yöntemlerine kıyasla) anlamak için daha tanıdık ve daha kolay görünmesi gerekir.

12

Hayır, ne istiyorsanız desteklenmiyor. Sınıf mühürlenmemişse ve yöntem statik değilse, sınıfı aynı adla farklı bir ad alanında devralabilir ve using'u değiştirebilir ve yöntemi geçersiz kılabilirsiniz. Ama bu sınırlı bir çözümdür.

En iyi seçeneğiniz, standart bir uzantı yöntemini farklı bir adla uygulamak ve tüm kullanımları değiştirmek olacaktır. Bu, büyük bir kod tabanında çok çalışma gibi görünebilir ve yoldaki insan hatalarına eğilimli olabilir - birisi orijinal yönteme yeni çağrı ekleme. Bununla birlikte, tek seferlik maliyet, kodunuzun şu anda davranışlarda değişiklikler yaptığınızın açık olmasıyla dengelenir; ve kendi özel FxCop kuralınızı (veya düzenli olarak çalıştırdığınız statik analiz aracını) yazarak insan hatalarına karşı koruyabilirsiniz.

+4

Visual Studio'nun Global Çözüm Bul ve Değiştir ... –

1

Bunu yapmak istediğinizi sanmıyorum. Kodu okuyan herkesi karıştırıyor. Bununla birlikte, bunun yapılabileceğine inanıyorum, ama hiçbir şekilde desteklenecek ya da garantilenecek kadar uzun bir yolla sağlanamayacağına inanıyorum. Eski günlerde, DLL dışa aktarılan işlevler yerine işlevleri enjekte edebiliriz. Antivirüs programları bu tekniği kullandı.

Görünüşe göre, birileri bu değer daha bu muhtemelen çok daha fazla sorun olacaktır unutmayın inject .NET methods.

anlamaya başardı. Yüklü her türlü ekstra yazılım yüklü her çeşit platformda QA'ya sahip olmanız gerekecektir (bir çeşit antivirüs kodunuzu bozabilir). Öyleyse, sadece başka herkesin önerdiği şeyi yapın - uzantı yönteminizi oluşturun ve sadece kod tabanınızın tamamını arayın ve değiştirin. Burada yapılan benzeri

+0

olduğunu Sadece uçucu yöntemler çok fazla çaba sarf etmeyecek ve aynı zamanda herhangi bir noktada bozulabilir, ancak çalışırsa Sadece tam güvenlik kodu yürütmeleri için çalışacaktır. CAS, orta veya düşük güvenli kum havuzlarında böyle bir şeyi engelleyecektir. –

+1

Bu yüzden bunu yapmamanı önerdim. – zmbq

İlgili konular