2011-11-11 30 views
6

Trước hết, vui lòng giải thích mọi lỗi đánh máy vì tiếng Anh không phải là ngôn ngữ mẹ đẻ của tôi.Xử lý ngoại lệ khi sử dụng tính năng tiêm phụ thuộc trong C# 4.0

Giả sử tôi muốn sử dụng phép xây dựng trong ứng dụng của mình. Vì vậy, ví dụ, tôi sẽ có một cái gì đó như thế:

public class FileDataProvider : IDataProvider 
{ 
    public MyData GetData() 
    { 
     // Get data from a file 
    } 
} 

public class DatabaseDataProvider : IDataProvider 
{ 
    public MyData GetData() 
    { 
     // Get data from a database 
    } 
} 

public class DataReader : IDataReader 
{ 
    private IDataProvider dataProvider; 

    public DataReader(IDataProvider dataProvider) 
    { 
     this.dataProvider = dataProvider; 
    } 

    public void OutputData() 
    { 
     MyData data = dataProvider.GetData(); 
     Console.WriteLine("{0}", data.ToString()); 
    } 
} 

Nếu tôi sử dụng constructor injection Tôi có theo định nghĩa không thể kiểm soát và cũng không có ý tưởng về các trường hợp cụ thể của việc thực hiện IDataProvider lớp đó sẽ được tiêm vào lớp DataReader của tôi. Có nghĩa là trong lớp DataReader của tôi tôi không biết những gì đang xảy ra trong phương pháp GetData bao gồm một thực tế là tôi không biết nếu nó có thể ném một ngoại lệ hay không và nếu như vậy loại ngoại lệ.

Trong phương thức OutputData của mình, tôi có nên đưa mã của mình vào khối try {} catch {} không và nếu có thì ngoại lệ nào tôi nên nắm bắt? Nếu tôi bắt IOException hoặc SQLException hoặc thực sự là bất kỳ loại ngoại lệ nào có nghĩa là tôi đang định trước một số cách mà IDataProvider có thể/nên được triển khai. Tôi không nghĩ nó tốt. Tôi cũng có thể có một XMLDataProvider hoặc NetworkResourceDataProvider được tiêm. Nhưng đồng thời tôi phải xử lý các ngoại lệ tại một số điểm.

Câu hỏi của tôi: Cách xử lý ngoại lệ chính xác và ghi nhật ký những gì xảy ra trong một ứng dụng bằng cách sử dụng đảo ngược kiểm soát nói chung và tiêm xây dựng cụ thể hơn? Còn cách nào đúng - nếu có - cho ném ngoại lệ trong một lớp thực hiện một giao diện?

-

Thêm một độ chính xác cho câu hỏi của tôi, tôi sẽ không sở hữu mã mà sẽ thực hiện IDataProvider vì vậy tôi thậm chí không thể chắc chắn rằng một ngoại lệ tùy chỉnh, nói DataProviderException sẽ được ném ra. Ngay cả khi tôi viết hướng dẫn cho nhà phát triển để làm như vậy ...

Trả lời

6

Theo ý kiến ​​của tôi, việc triển khai cụ thể IDataProvider sẽ bắt các ngoại lệ thích hợp (I/O cho trình duyệt tệp, nhà cung cấp SQL cho DB) và tăng ngoại lệ khác lỗi chung nhận dữ liệu, ví dụ: DataProviderException. Nếu cần, bạn có thể lưu trữ ngoại lệ ban đầu làm thuộc tính ngoại lệ bên trong để thông tin đó không bị mất.

Làm theo cách này người tiêu dùng DataReader chỉ phải xử lý ngoại lệ cụ thể này và được che chắn từ các chi tiết. Điều đó giả định người tiêu dùng có cách xử lý ngoại lệ, tức là thử lại là có thể.

+0

Đồng ý. Lớp người tiêu dùng của bạn không cần biết điều gì đã xảy ra. Nó chỉ có thể lấy một ngoại lệ đóng gói với một ngoại lệ wrapper phổ biến và nếu cần phải cung cấp thêm thông tin - như nếu ngoại lệ là có thể phục hồi hay không - xác định nó trên ngoại lệ wrapper của bạn. –

+0

Tôi nghĩ về nó nhưng nó sẽ chỉ hoạt động nếu tôi sở hữu mã thực hiện 'IDataProvider' không phải là trường hợp. Vì vậy, tôi thực sự không thể chắc chắn các nhà phát triển khác sẽ ném một 'DataProviderException'. Tôi vẫn có thể thêm một số hướng dẫn nhưng tôi không thể chắc chắn rằng họ sẽ được theo sau ... Tôi sẽ cập nhật câu hỏi của tôi để phản ánh điều này. – Guillaume

+2

@Guillaume: Sau đó, không có nhiều hữu ích mà có thể được thực hiện và tôi đồng ý với John Saunders: không bắt nó nếu bạn không thể xử lý nó – BrokenGlass

7

Theo định nghĩa, nếu bạn không biết cách xử lý ngoại lệ, thì đừng bắt nó. Giai đoạn.

+0

Vì vậy, trường hợp ngoại lệ nên được xử lý? Một nơi nào đó trong thùng chứa DI của tôi? Làm thế nào tôi có thể biết rằng một cái gì đó đã đi sai một nơi nào đó để cảnh báo người dùng trước khi bị treo ứng dụng nếu cần thiết chẳng hạn. – Guillaume

+0

Tại sao công việc của vùng chứa DI của bạn lại cảnh báo người dùng? Bạn có một thùng chứa khác cho Windows Biểu mẫu so với Biểu mẫu web không? Không? Sau đó, vùng chứa của bạn sẽ không có gì để làm với giao diện người dùng (như người dùng cảnh báo). Và bạn sẽ cảnh báo người dùng _about_ là gì? Bạn sẽ cung cấp cho họ bất kỳ thông tin nào họ có thể sử dụng? Cố gắng không "xử lý" ngoại lệ chút nào, sau đó xem điều gì xảy ra. –

5

Hãy để tôi bắt đầu bằng cách nói tiếng Anh của bạn tốt hơn tiếng Pháp của tôi, vì vậy hãy nói về ca.

Bạn sẽ không làm điều gì đó đặc biệt vào thời điểm này trong mã nếu SQLException xảy ra, đúng không?

Nói chung, bạn không muốn bắt ngoại lệ cho đến khi bạn biết mình sẽ làm gì với nó. Ngoại lệ thường phục vụ để cung cấp cho nhà phát triển một cách để biết những gì đã xảy ra: đó là lý do tại sao bạn nhận được một dấu vết ngăn xếp để đi cùng với họ. Vì vậy, nó thường tốt hơn để cho họ bong bóng lên đến một điểm ngay bên dưới giao diện người dùng, nơi bạn có thể đăng nhập chúng và nói cho người dùng biết điều gì đó bất ngờ xảy ra.