[C#] Nette manier globale variabelen

Pagina: 1
Acties:
  • 191 views sinds 30-01-2008
  • Reageer

  • Equator
  • Registratie: April 2001
  • Laatst online: 16:54

Equator

Crew Council

🦺#Rodekruis #whisky #barista

Topicstarter
Enige tijd geleden heb ik in een topic het advies gekregen om Databaseconnectie zaken in een class te plaatsen.

Dit heb ik ter harte genomen, en ben daar redenlijk in geslaagd. :*)

Ik heb een class gemaakt, die o.a. een paar public strings bevat, en een public bool.
Tijdens het laden van de aplpicatie (MDI container) worden er enkele preferences uit het register gehaald, waarmee ik de publieke strings vul.

Denk daarbij aan de servernaam (SQL server), en de naam van de database.
Als de publieke bool false is, moet er ook een sql username en een sql password worden meegegeven. Indien de bool true is, wordt de connectionstring gemaakt met de windows security gegevens.
hier een uitgekleed stukje van mijn class
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
using System;

namespace WindowsApplication3
{
    /// <summary>
    /// Summary description for Class1.
    /// </summary>
    public class Class1
    {
        private string strConnection = null;
        public string strServername = null;
        public string strDBname = null;
        public string sqluser = null;
        public string sqlpass = null;
        public bool _UseIntegratedSecurity = false;

        public void Connect()
        {
            if (this._UseIntegratedSecurity == false)
            {
                // We gebruiken SQL userid en pass.
                this.strConnection = "server=" + this.strServername + "; uid=" + this.sqluser + "; pwd=" + this.sqlpass + ";database=" + this.strDBname + "";
            }
            else
            {
                //we gebruiken Integrated Windows Security
                this.strConnection = "server=" + this.strServername + "; Integrated Security = SSPI; database=" + this.strDBname + "";
            }
        }
    }
}


Echter, blijkt nu dat wanneer ik vanauit een MDI child gebrui ga maken van de class, dat deze gegevens (public strings) leeg zijn.
Nou is het op zich niet erg dat ik elke keer mijn servernaam en databsenaam uit het register moet plukken om deze opnieuw te zetten, maar ik zit een beetje met mijn sqluser en password.
Deze worden (indien de instelling "gebruik sql authentication" aanstaat) via een inlogscherm gezet in de class. Deze moeten dus statisch blijven.

Ik kan eventueel deze gegevens wel in het register schrijven en d.m.v. de CryptoGraphicLibrary deze gegevens 3DES versleutelen, maar dat vind ik een smerige houtje touwtje oplossing.

Ik heb dus gezocht op google, en kwam op de mogelijkheid om public strings static te maken.
Zoiets dus..
C#:
1
2
3
4
5
6
private string strConnection = null;
public static string strServername = null;
public static string strDBname = null;
public static string sqluser = null;
public static string sqlpass = null;
public static bool _UseIntegratedSecurity = false;


Echter weet ik niet of dit een nette manier is. Daar mijn Class public is, kan deze dan niet worden misbruikt.

Mijn vraag aan julie is dus: Wat is een nette(re) manier om dit soort gegevens globaal te onthouden.

  • P_de_B
  • Registratie: Juli 2003
  • Niet online
Kun je dit niet beter in je App.Config bijhouden? Je hebt het dan niet hard in je applicatie gecodeerd. Encryptie kun je ook hierin toepassen.

Oops! Google Chrome could not find www.rijks%20museum.nl


  • Equator
  • Registratie: April 2001
  • Laatst online: 16:54

Equator

Crew Council

🦺#Rodekruis #whisky #barista

Topicstarter
De app.config functie creeerd toch een xml bestand. Daar zou ik dan inderdaad in willen versleutelen.

Maar is het echt af te raden om deze gegevens als static in de class te zetten :?

  • P_de_B
  • Registratie: Juli 2003
  • Niet online
CyberJ schreef op donderdag 16 december 2004 @ 09:10:
De app.config functie creeerd toch een xml bestand. Daar zou ik dan inderdaad in willen versleutelen.

Maar is het echt af te raden om deze gegevens als static in de class te zetten :?
Nou, als er iets wijzigt in de server (naam, wachtwoord oid) moet je je applicatie opnieuw compilen, dat lijkt me niet erg handig.

Oops! Google Chrome could not find www.rijks%20museum.nl


  • Equator
  • Registratie: April 2001
  • Laatst online: 16:54

Equator

Crew Council

🦺#Rodekruis #whisky #barista

Topicstarter
Nee, ik heb een apart form waarin ik d.m.v. de Application.UserAppDataSettings de preferences wegschrijf in het register. Ik kan @ runtime de servernaam dus aanpassen.
Ik ben wel een groentje in programmeren, maar ik ben geen idioot.

  • whoami
  • Registratie: December 2000
  • Laatst online: 18:00
P_de_B schreef op donderdag 16 december 2004 @ 09:06:
Kun je dit niet beter in je App.Config bijhouden? Je hebt het dan niet hard in je applicatie gecodeerd. Encryptie kun je ook hierin toepassen.
Configuratie gegevens die user - afhankelijk zijn bewaar je beter niet in de app.config.
De app.config staat nl meestal in de Program Files directory, en deze directory is 'read only' voor niet-Administrators. Een gewone gebruiker zal dus geen toelating hebben om naar deze file te schrijven.
Daarbij komt ook nog eens dat een PC door meerdere gebruikers kan gebruikt worden. Dat wil dus zeggen dat deze user-specifieke informatie iedere keer 'gereset' wordt als iemand anders die pc gebruikt.

Het is dus beter om user-specifieke config settings in een config file te bewaren die in de 'configsettings' directory van de user staat, of in de juiste registry setting.

https://fgheysels.github.io/


  • P_de_B
  • Registratie: Juli 2003
  • Niet online
whoami schreef op donderdag 16 december 2004 @ 09:19:
[...]


Configuratie gegevens die user - afhankelijk zijn bewaar je beter niet in de app.config.
De app.config staat nl meestal in de Program Files directory, en deze directory is 'read only' voor niet-Administrators. Een gewone gebruiker zal dus geen toelating hebben om naar deze file te schrijven.
Daarbij komt ook nog eens dat een PC door meerdere gebruikers kan gebruikt worden. Dat wil dus zeggen dat deze user-specifieke informatie iedere keer 'gereset' wordt als iemand anders die pc gebruikt.

Het is dus beter om user-specifieke config settings in een config file te bewaren die in de 'configsettings' directory van de user staat, of in de juiste registry setting.
Ok, daar heb je gelijk in. Maar is het niet zo dat het bestand sowieso read-only is?

Oops! Google Chrome could not find www.rijks%20museum.nl


  • pjvandesande
  • Registratie: Maart 2004
  • Laatst online: 09:50

pjvandesande

GC.Collect(head);

P_de_B schreef op donderdag 16 december 2004 @ 09:27:
[...]


Ok, daar heb je gelijk in. Maar is het niet zo dat het bestand sowieso read-only is?
Ja, het is niet de bedoeling naar je App.config te schrijven @ runtime.

  • Equator
  • Registratie: April 2001
  • Laatst online: 16:54

Equator

Crew Council

🦺#Rodekruis #whisky #barista

Topicstarter
Ok, App.config is dus ook niet mogelijk. (of iig niet aan te raden.)
Blijf ik bij mijn idee om de gegevens als static in de class te plaatsen. Of heeft er iemand een reden om dit echt niet te doen. Ik heb geen zin om na lang werken een kraakbaar iets te hebben.
(behalve dat je er wat van leert)

Ik kan me voorstellen dat als ik deze class in een aparte dll had geplaatst dat het wel onveilig was, daar je die DLL dan ook vanauit een ander programma kan misbruiken.

  • whoami
  • Registratie: December 2000
  • Laatst online: 18:00
Je kan natuurlijk het spul ook zo creeëren dat jeen connection string doorgeeft aan je connect method.

https://fgheysels.github.io/


  • Equator
  • Registratie: April 2001
  • Laatst online: 16:54

Equator

Crew Council

🦺#Rodekruis #whisky #barista

Topicstarter
whoami schreef op donderdag 16 december 2004 @ 10:26:
Je kan natuurlijk het spul ook zo creeëren dat jeen connection string doorgeeft aan je connect method.
Ja, tuurlijk, maar dan moet ik vanuit elke apart formulier een connectionstring genereren en doorgeven aan de Connect method.
Echter zit ik dan nog steeds met de username en wachtwoord.

Die wil ik dan ergens vast hebben. Ik kan natuurlijk in de MDI container (frmMain) een public static string zetten, dan kan ik die ten alle tijde aanroepen, maar dan vind ik het netter om deze gewoon in de class te plaatsen.

  • pjvandesande
  • Registratie: Maart 2004
  • Laatst online: 09:50

pjvandesande

GC.Collect(head);

Je kan er een apparte class voor maken met een private ctor, zodat er geen instantie van gemaakt kan worden met allemaal public static members.

Het doorgeven wat Whoami zegt werkt ook prima, je leest het dus 1x in bij het starten van je applicatie en geeft ze elke keer door aan je DAL. Je kan een connection string ook in je App.config zetten als het niet user gerelateerd is en deze in je DAL elke keer inlezen.

  • pjvandesande
  • Registratie: Maart 2004
  • Laatst online: 09:50

pjvandesande

GC.Collect(head);

*kick*

Ik heb nu zelf een soort mask gemaakt over de .config file. Het is een singleton setting class met wat getters en setters.

Nu geeft alleen net iemand anders aan die ook aan het project werkt dat dit niet echt idiaal is en laat liever in de DAL elke keer alles uit de config file.

Nu was ik alleen benieuwd naar jullie mening, want hij vind dat je zo onnodig veel geheugen gebruikt.

  • whoami
  • Registratie: December 2000
  • Laatst online: 18:00
Ik dacht dat de config - file (app.config) in Windows applicaties ook al 1x ingelezen wordt (bij het starten van de applicatie) en wordt het in het geheugen bijgehouden; als je iets wijzigt in je config file, terwijl je app. open staat, dan zal je applicatie die wijzigingen niet weten. (Dit in tegenstelling tot web applicaties icm web.config).

Wat je kan doen, is een soort van 'wrapper' maken rond ApplicationSettings.ConfigSettings zodanig dat je op een 'strong typed' manier je configuratie-opties kunt ophalen. Dit kan ervoor zorgen dat je minder run-time fouten hebt (of toch de kans daarop verminderd).
Ik snap wel niet waarom je ook 'setters' hebt geimplementeerd, wan naar de app.config zou je in principe niet mogen schrijven.

https://fgheysels.github.io/


  • pjvandesande
  • Registratie: Maart 2004
  • Laatst online: 09:50

pjvandesande

GC.Collect(head);

whoami schreef op maandag 03 januari 2005 @ 14:47:
[...]
Ik snap wel niet waarom je ook 'setters' hebt geimplementeerd, wan naar de app.config zou je in principe niet mogen schrijven.
Dat is een goed punt, maar een aantal settings mogen wel geset worden. Deze zijn user gerelateerd en worden ook in de goede plekken opgeslagen.

De setting class heeft een Event SettingChanged, deze word getriggerd als zo'n setting gewijzigd word zodat indien nodig dingen geupdate kunnen worden.

Maar nu heb ik dus database gerelateerde settings, die eigelijk alleen binnen de DAL worden gebruikt en wat user gerelateerde die weer in de PL worden gebruikt.

Nu vraag ik mij af of het niet beter is om dit te scheiden in twee classes. Of om de database gerelateerde settings echt alleen binnen de DAL te houden en bij de init van de DAL de settings te laden uit de .config file.

  • sorted.bits
  • Registratie: Januari 2000
  • Laatst online: 18:32
Is het zowiezo niet de bedoeling dat je alle variablen in een class private maakt en daar functies voor maakt ?

  • pjvandesande
  • Registratie: Maart 2004
  • Laatst online: 09:50

pjvandesande

GC.Collect(head);

sorted.bits schreef op maandag 03 januari 2005 @ 18:20:
Is het zowiezo niet de bedoeling dat je alle variablen in een class private maakt en daar functies voor maakt ?
Ik heb private members met getters en bij sommige wat setters, waarvan de setters allemaal een event triggeren.

Verwijderd

Ik denk zelf dat je met een singleton er al uit kan komen. zoek maar ff op google hoe je die moet maken. Maar er is altijd maar 1 instance en je kan hem overal vanaf aanroepen

  • pjvandesande
  • Registratie: Maart 2004
  • Laatst online: 09:50

pjvandesande

GC.Collect(head);

Verwijderd schreef op dinsdag 04 januari 2005 @ 09:10:
Ik denk zelf dat je met een singleton er al uit kan komen. zoek maar ff op google hoe je die moet maken. Maar er is altijd maar 1 instance en je kan hem overal vanaf aanroepen
Ik geef toch al aan dat het al een singleton is.

Wanneer moet ik trouwens de settings inladen in de singleton, ik doe het nu in de ctor. Maar het nadeel is dat er in de ctor dus een exception kan worden gegooit. Moet ik hier nu een apperte method voor maken?

Verwijderd

|:( niet goed gelezen.


iig over het vullen van je singelton. gewoon in je constructor (of een initialize() method aanroepen in je constructor). Je zult die singleton altijd aanspreken via een constructie zoals: "mySingleton.Current.LoginName" dus bij de private constructor de default waardes uit bijvoorbeeld je app.config laten lezen is goed genoeg.

  • pjvandesande
  • Registratie: Maart 2004
  • Laatst online: 09:50

pjvandesande

GC.Collect(head);

Verwijderd schreef op dinsdag 04 januari 2005 @ 13:05:
|:( niet goed gelezen.


iig over het vullen van je singelton. gewoon in je constructor (of een initialize() method aanroepen in je constructor). Je zult die singleton altijd aanspreken via een constructie zoals: "mySingleton.Current.LoginName" dus bij de private constructor de default waardes uit bijvoorbeeld je app.config laten lezen is goed genoeg.
Maar dan zit het eigelijk zo dat je elke keer als mySingleton.Current.LoginName een LoadSettingsException oid kan gooien. Want de settings file kan bijvoorbeeld niet worden gevonden. Het lijkt in mijn ogen zo onlogisch om elke keer als ik een setting lees deze exception af te vangen, iig de mogelijk heid bieden.

Want als mySingleton.Current nog null is word de instantie aangemaakt en de settings geladen als ik dit in de ctor doe.

Daarom vroeg ik mij af hoe ik dit netjes zou kunnen doen, een extra flag oid iets van 'bool SettingsLoaded'?

  • pjvandesande
  • Registratie: Maart 2004
  • Laatst online: 09:50

pjvandesande

GC.Collect(head);

Afbeeldingslocatie: http://crew.tweakers.net/SmartDoDo/gotverkiezing2004/kick.gif

  • pjvandesande
  • Registratie: Maart 2004
  • Laatst online: 09:50

pjvandesande

GC.Collect(head);

Afbeeldingslocatie: http://crew.tweakers.net/SmartDoDo/gotverkiezing2004/kick.gif

Laatste poging... O-)

Verwijderd

Je kan als je wil ook je instantie opnieuw 'killen'

Iets in de aard van :

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
public MyClass GetInstance
{
  get
  {
      if ( myInstance == null )
      {
         myInstance = new MyClass();
         if ( ! myInstance.Loaded )
            myInstance = null;
      }
       return myInstance;
  }
}

[ Voor 10% gewijzigd door Verwijderd op 07-01-2005 08:59 ]


  • pjvandesande
  • Registratie: Maart 2004
  • Laatst online: 09:50

pjvandesande

GC.Collect(head);

En hoe ga ik de settings dan loaden (uit me config file en register lezen)?

Nouja. niet hoe... maar waar? Is het dan verstandig om dat in me ctor te doen, met alle gevolgen van dien. Want de ctor word altijd aangeroepen als er nog geen Instantie is van de settings class. Dus overal waar ik Settings.GetInstace() doe kan ik een exception verwachten.
Pagina: 1