简体   繁体   中英

Different properties based on implementation of interface

Perhaps this is simple, but I'm lost. I am writing a small app that is supposed to read data from database, export data to CSV, and finally upload it to server. That simple.

Since reading and exporting are completely different responsibilities, I created IDataFeeder (to retrieve data) and IDataExporter (to create CSV and upload it).

public interface IDataFeeder
{
    DataTable GetData();
}

public interface IDataExporter
{
    bool ExportData(DataTable data);
}

public class DataFeeder : IDataFeeder {}
public class DataExporter : IDataExporter {}

DataFeeder.GetData() will use ADO.NET code. DataExporter.ExportData() method will do:

// dataFeeder <- ctor injection
dataFeeder.GetData("<stored_proc_1>"); // Problem
dataFeeder.GetData("<stored_proc_2>");
// generate csv 
// upload csv

Problem:

I cannot have/don't want IDataFeeder.GetData(string sproc) because that would become database specific. If sometime I've to read data from fixed path file, I will not need this parameter.

As far as I've understood, you always want to read the same data / execute the same stored procedure. Why don't you implementent GetData() like this:

public DataTable GetData() {
    execute <stored_procedure_1>;
    execute <stored_procedure_2>;
    return whatever;
}

I'm not able to post comments yet, sorry if this answer is not helpful.

Keep GetData method of the interface parameterless as you described in the beginning of your question. Have different implementations of IDataFeeder interface take the domain specific parameters (like connectionstrings, db names etc) through their constructor on initialization that way you can keep a generic interface.

One way you can achieve this is with an an abstract class. You can then create specific implementations that to suit whatever kind of data feeder you need.

public abstract class DataFeederBase : IDataFeeder
{
        public abstract DataTable GetData();
}

public class DataFeederByString : DataFeederBase
{
        private string _storedProcedure = string.Empty;

        public DataFeederByString(string storedProcedure)
        {
            _storedProcedure = storedProcedure;
        }

        public override DataTable GetData()
        {
           //Implementation using stored procedure string
            return new DataTable();
        }
    }

    public class DataFeederByFixedPath : DataFeederBase
    {
        public override DataTable GetData()
        {
            //Implement using fixed path
            return new DataTable();
        }
    }

Then consume in the UI

 var feederByString = new DataFeederByString("mystring");
 feederByString.GetData();

 var feederByFixedPath = new DataFeederByFixedPath();
 feederByFixedPath.GetData();

Hope that helps.

Create an abstract class which extends IDataFeeder as shown below

    public abstract class AbstractDataFeeder implements IDataFeeder{

   // assuming that your data is a list of string
   public abstract List<String> fetchData(Object...args);

}

public class DBDataFeeder extends AbstractDataFeeder{

   // override fetchData
   public List<String> fetchData(Object...args){

   }

}

public class FileDataFeeder extends AbstractDataFeeder{

   // override fetchData
   public List<String> fetchData(Object...args){

   }

}

Now define properties of both DBDataFeeder and FileDataFeeder and then override fetch data passing whatever arguments required.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM