Uit te voeren stappen opslaan voor andere klasse

  • Onderwerp starter Onderwerp starter DMK
  • Startdatum Startdatum
Status
Niet open voor verdere reacties.

DMK

Gebruiker
Lid geworden
5 nov 2013
Berichten
31
Hallo,

Ik wil in mijn programma gegevens op kunnen slaan en kunnen laden uit een database.
Het enige probleempje waar ik nu tegenaan loop is dat er 2 type databases zijn die ik in 1 klasse moet kunnen benaderen.

Mijn klassestructuur ziet er als volgt uit:


Dal
| |
| |__ Webserver (gekoppeld aan andere database)
| |__ Eigen Database
|
|
|__ Wrapper


De DAL krijgt binnen wat er moet gebeuren (bv een waarde uit eigen database opvragen of schrijven naar webserver etc...)
De Wrapper is ervoor om gegevens om te zetten.

Ik roep een methode aan in de Wrapper (met als parameter: database, uitvoer)
De wrapper moet eigenlijk de juiste stappen returnen. Als ik de eigen database gebruik zijn er bijvoorbeeld 4 stappen nodig om een verbinding te maken en waardes uit de database te halen. De stappen moeten gereturnd worden (niet de waarden).

De wrapper wil ik geen verbinding laten maken met de database, alleen de stappen laten genereren.

Is dit mogelijk? zodat ik de gereturnde waardes uit de wrapper in de DAL kan laten uitvoeren?


Het is allemaal wat lastig uit te leggen maar hoop dat het toch duidelijk genoeg is.

Bedankt!
 
Wat bedoel je met 'stappen'?
Heb je wat voorbeelden van je method signatures?
 
Wat bedoel je met 'stappen'?
Heb je wat voorbeelden van je method signatures?

Met de stappen bedoel ik het volgende. Deze stappen staan nu nog in de DAL.
In mijn programma wil ik het zo hebben dat de Wrapper deze stappen terug geeft.

In de dal wil ik de Wrapper classe aanroepen met daarin welke database ik wil gebruiken. Afhankelijk van de database moet de wrapper de juiste stappen terug geven.
Een voorbeeld van de stappen is als volgt: (Dit voor bijvoorbeeld de connectie naar een Access bestand)
Stap 1: OdbcDataAdapter da = new OdbcDataAdapter();
Stap 2: DataSet ds = new DataSet();
Stap 3: DataTable dt = new DataTable();
Stap 4: da.SelectCommand = new OdbcCommand(@"SELECT * FROM Recepten", connectie);
Stap 5: da.Fill(ds, "Analyses");
Stap 6: dt = ds.Tables["Analyses"];

Wanneer ik verbinding maak met de webservice zullen dit andere stappen zijn. Ook is het mogelijk dat er meer stappen nodig zijn of minder.
 
Misschien zo iets als dit, als je nieuwe datasource hebt is het eenvoudig toe te voegen.

Je klass die zorgt waar je de data haalt implement de IDataSource interface en moet dus de method hebben die wordt beschreven (GetAnalysys).

In de wrapper geef je een enum mee met wat je wilt, dan wordt in de wrapper de juiste source aangemaakt en de data gereturned.



[CPP]public class Analyses
{
public string Name { get; set; }
}

public interface IDataSource
{
List<Analyses> GetAnalyses();
}

public class MsSqlDataSource : IDataSource
{
public List<Analyses> GetAnalyses()
{
//code to get MsSql data
throw new NotImplementedException();
}
}

public class AccessDataSource : IDataSource
{
public List<Analyses> GetAnalyses()
{
//code to get Access data
throw new NotImplementedException();
}
}
public class WebServiceDataSource : IDataSource
{
public List<Analyses> GetAnalyses()
{
//code to get WebService data
throw new NotImplementedException();
}
}

public enum DataSource
{
Access,
MsSql,
WebService
}

public class DataAccessWrapper
{
public List<Analyses> GetAnalyses(DataSource requestedDataSource)
{
IDataSource source;

switch (requestedDataSource)
{
case DataSource.Access:
source = new AccessDataSource();
break;
case DataSource.MsSql:
source = new MsSqlDataSource();
break;
case DataSource.WebService:
source = new WebServiceDataSource();
break;
default:
throw new ArgumentOutOfRangeException("requestedDataSource");
}

return source.GetAnalyses();
}
}[/CPP]
 
Bedankt, maar als ik het goed heb wordt de connectie nu in de wrapper gemaakt?
Dit wil ik eigenlijk in de DAL laten gebeuren, de wrapper moet alleen aangeven welke stappen de DAL moet uitvoeren
 
Nee, de class die nodig is wordt in de wrapper gemaakt, de datasource classes staan gewoon in de DAL dll
 
Nee, de class die nodig is wordt in de wrapper gemaakt, de datasource classes staan gewoon in de DAL dll

Ik heb geen bestand met de naam DAL.dll Ik gebruik hiervoor een klasse.
Kun je mij even vertellen welke methode ik in welke klasse moet zetten.
 
De wrapper je een soort api voor je data op te vragen (toch?) deze staat apart.
De rest kan bij elkaar maar zijn gewoon altijd nog aparte classes.

Als je niet het principe van de interface wilt gebruiken en alles in 1 DAL class wilt proppen kun je methods daar maken zoals:

Code:
public List<Analyses> GetAnalysesFromAccess()
public List<Analyses> GetAnalysesFromMsSql()
public List<Analyses> GetAnalysesFromWebService()

en dan krijgt je wrapper zoiets als dit

[CPP]public List<Analyses> GetAnalyses(DataSource requestedDataSource)
{
DAL source = new DAL();

switch (requestedDataSource)
{
case DataSource.Access:
return source.GetAnalysesFromAccess();
case DataSource.MsSql:
return source.GetAnalysesFromMsSql();
case DataSource.WebService:
return source.GetAnalysesFromWebService();
default:
throw new ArgumentOutOfRangeException("requestedDataSource");
}
}[/CPP]

Maar deze method kan dan ook gewoon in de DAL class, en is het hele idee van een wrapper eigenlijk weg.

Of ik begrijp niet goed wat je precies wilt? 1 method met input waar je de data vandaan wilt, deze method roept de goede aan (de goede stappen (zoals je ze noemt) staan in de method die hij aanroept).
 
Ik heb nu de volgende code:

DAL
public class AnalyseDAL
{
DBWrapper dbWrapper = new DBWrapper();

public DataTable Lezen(string database, int id)
{
dbWrapper.GetAnalyses(DataSource.Access);

}

internal void RapportOpslaan(string database, int id, double inweegWaarde)
{

}
}

ENUM
public enum DataSource
{
Access,
MsSql,
WebService
}

WRAPPER
public class DBWrapper
{

public List<Analyses> GetAnalyses(DataSource requestedDataSource)
{
IDataSource source;

switch (requestedDataSource)
{
case DataSource.Access:
source = new AccessDataSource();
break;
case DataSource.MsSql:
source = new MsSqlDataSource();
break;
case DataSource.WebService:
source = new WebServiceDataSource();
break;
default:
throw new ArgumentOutOfRangeException("requestedDataSource");
}

return source.GetAnalyses();
}

public class MsSqlDataSource : IDataSource
{
public List<Analyses> GetAnalyses()
{
//code to get MsSql data
throw new NotImplementedException();
}
}

public class AccessDataSource : IDataSource
{
public List<Analyses> GetAnalyses()
{
//code to get Access data
throw new NotImplementedException();
}
}
public class WebServiceDataSource : IDataSource
{
public List<Analyses> GetAnalyses()
{
//code to get WebService data
throw new NotImplementedException();
}
}
}

IDataSource
public class Analyses
{
public string Name { get; set; }
}

public interface IDataSource
{
List<Analyses> GetAnalyses();
}

Ik krijg geen foutmeldingen tot nu toe dus de structuur werkt.
Hoe krijg ik nu de volgende gegevens in mijn lijst voor bijvoorbeeld ACCESS source. Dus deze regels?

Stap 1: OdbcDataAdapter da = new OdbcDataAdapter();
Stap 2: DataSet ds = new DataSet();
Stap 3: DataTable dt = new DataTable();
Stap 4: da.SelectCommand = new OdbcCommand(@"SELECT * FROM Recepten", connectie);
Stap 5: da.Fill(ds, "Analyses");
Stap 6: dt = ds.Tables["Analyses"];
 
dat komt hier:

[CPP]public class AccessDataSource : IDataSource
{
public List<Analyses> GetAnalyses()
{
//code to get Access data
throw new NotImplementedException();
}
}[/CPP]

Ik heb hier List<Analyses> gebruikt om te returnen maar je kunt ook DataTable gebruiken uiteraard, de interface geeft aan wat voor methods het zijn.



het idee is dat als je nog een source wilt gebruiken, bijvoorbeeld gewoon een txt file. Dan hoef je alleen de enum dus uit te breiden met 'File'

een FileDataSource class maken die IDataSource implement, en de method aanpassen in de wrapper

[CPP]public class FileDataSource : IDataSource
{
public List<Analyses> GetAnalyses()
{
//read analyses.txt

//get data

//return list
}
}[/CPP]
 
Laatst bewerkt:
Ik heb nog een vraag. Mijn code ziet er nu als volgt uit:

DAL
public class AnalyseDAL
{
DBWrapper dbWrapper = new DBWrapper();

public void Lezen(DataSource dataSource)
{
List<Analyses> stappen = dbWrapper.HaalAnalyseOp(dataSource);

}

internal void RapportOpslaan(string database, int id, double inweegWaarde)
{

}
}



WRAPPER
public class DBWrapper
{

public List<Analyses> HaalAnalyseOp(DataSource requestedDataSource)
{
IDataSource source;

switch (requestedDataSource)
{
case DataSource.Access:
source = new AccessDataSource();
break;
case DataSource.MsSql:
source = new MsSqlDataSource();
break;
case DataSource.WebService:
source = new WebServiceDataSource();
break;
default:
throw new ArgumentOutOfRangeException("requestedDataSource");
}

return source.GetAnalyses();
}

public class MsSqlDataSource : IDataSource
{
public List<Analyses> GetAnalyses()
{
//code to get MsSql data
throw new NotImplementedException();
}
}

public class AccessDataSource : IDataSource
{
public List<Analyses> GetAnalyses()
{
var lijst = new List<Analyses>();
lijst.Add(new Analyses() { Stap1 = "OdbcDataAdapter da = new OdbcDataAdapter();",
Stap2 = "DataSet ds = new DataSet();" });
return lijst;
}
}

public class WebServiceDataSource : IDataSource
{
public List<Analyses> GetAnalyses()
{
//code to get WebService data
throw new NotImplementedException();
}
}
}

IDATASOURCE
public class Analyses
{
public string Stap1 { get; set; }
public string Stap2 { get; set; }
}

public interface IDataSource
{
List<Analyses> GetAnalyses();
}

Nu krijg ik de stappen in de vorm van een lijst terug in de DAL.
Deze zijn van het type string.

Stap 1 is nu "OdbcDataAdapter da = new OdbcDataAdapter();"
Stap 2 is nu "DataSet ds = new DataSet();"
Enz....

Hoe kan ik deze stappen nu uitvoeren in de DAL?
 
Het is in .NET mogelijk om code dynamisch uit te voeren (dynamic code execution), maar ik vraag me af waarom je dat in dit geval zou willen. Wat is er bijvoorbeeld mis met het idee van Bloodshed om voor iedere vorm van communicatie (Access/Database/Webservice) een eigen klasse voor de communicatie te schrijven? Naast het feit dat eventuele fouten al tijdens het compileren kunnen worden gedetecteerd en het makkelijker debuggen is, ben je toch al bezig met het customizen van iedere vorm van communicatie en kan je dat dan net zo goed in hetzelfde project doen met aparte klassen voor iedere vorm van communicatie.
 
Het is in .NET mogelijk om code dynamisch uit te voeren (dynamic code execution), maar ik vraag me af waarom je dat in dit geval zou willen. Wat is er bijvoorbeeld mis met het idee van Bloodshed om voor iedere vorm van communicatie (Access/Database/Webservice) een eigen klasse voor de communicatie te schrijven? Naast het feit dat eventuele fouten al tijdens het compileren kunnen worden gedetecteerd en het makkelijker debuggen is, ben je toch al bezig met het customizen van iedere vorm van communicatie en kan je dat dan net zo goed in hetzelfde project doen met aparte klassen voor iedere vorm van communicatie.


Dit verhaal klopt inderdaad. Het probleem is opgelost.

Hartelijk dank hiervoor:thumb:
 
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan