First of all, please excuse any typo as English is not my native language.
Let's say I want to use constructor injection in my application. So for example, I will have something like that:
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());
}
}
If I use constructor injection I have by definition no control nor idea about the concrete instance of the class implementing IDataProvider that will be injected into my DataReader class. Meaning that in my DataReader class I don't know what's going on in GetData method including the fact that I don't know if it may throw an exception or not and if so what kind of exception.
In my OutputData method, should I wrap my code into a try { } catch { } block and if so what exception should I catch? If I catch IOException or SQLException or actually any kind of exception means that I am preconceiving some ways IDataProvider may/should be implemented. I don't think it is good. I could also have an XMLDataProvider or NetworkResourceDataProvider injected. But at the same time I must handle exceptions at some point.
My question: What is the correct way of handling exception and logging what happens in an application using inversion of control in general and constructor injection more specifically? Also what is the correct way - if any - for throwing exceptions in a class that implements an interface?
--
Adding a precision to my question, I will not own the code that will implement IDataProvider so I can't even be sure that a custom exception, say DataProviderException
will be thrown. Even if I write guidelines for developers to do so...
By definition, if you don't know how to handle an exception, then don't catch it. Period.
In my opinion the concrete implementations of IDataProvider
should catch the appropriate exceptions (I/O for file povider, SQL for DB provider) and raise another exception that communicates a general error getting the data, i.e. a DataProviderException
. If needed you can store the original exception as the inner exception property so that info is not lost.
Doing it this way the DataReader
consumer only has to handle this particular exception and is shielded from the details. That assumes the consumer has a way of handling the exception, i.e. a retry is possible.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With