Avatar billede CodingJoe Nybegynder
10. oktober 2012 - 00:22 Der er 35 kommentarer og
1 løsning

Holde på et objekt 'state' andre steder i applikationen

Jeg forsøger at gøre værdierne i mit objekt tilgængelig i andre dele af min applikation. Jeg kan ikke bruge sessions værdier eller cookies, da jeg opererer nede noget rent c#. Jeg vil heller ikke persistere værdierne i en fil eller andet.

Jeg vil blot gerne fx. læse en værdi sat fra et andet sted i min applikation.

fx. en klasse med get og set muligheder.

Jeg setter en værdi i starten af min applikation....længere fremme i fx en hel anden klasse og metode, vil jeg gerne tilgå den værdi tidligere sat. Er der nogen, der kan give mig en god ide til det?

Jeg vil helst undgå nedarvning, da det jo betyder alle mine klasser skal implementere min hovedklasse, hvis min get og set ligger i denne...

Forslag? Jeg giver sprøde points til det bedste og simpleste... :)
Avatar billede arne_v Ekspert
10. oktober 2012 - 00:41 #1
singleton pattern
Avatar billede Syska Mester
10. oktober 2012 - 00:58 #2
static property på en klasse ... og den mere advanceret udgave er så Singleton ... :-)

http://msdn.microsoft.com/en-us/library/ff650316.aspx

Men jeg vil mene du er på vej i den forkerte retning hvis du tilgår data på den måde. Der kan være grunde til at bruge singleton og gøre som du er ved ... men de er få.
Avatar billede arne_v Ekspert
10. oktober 2012 - 02:07 #3
Singleton har faaet et daarligt ry de sidste 6-8 aar og det kan da ogsaa give problemer, men det behoever ikke vaere saa slemt. Bl.a. hjaelper det gevaldigt hvis det er readonly properties.

AT behovet er der illsutreres af at de fleste DI framworks kommer med support for "singleton object", hvor alle faar samme objekt.
Avatar billede CodingJoe Nybegynder
10. oktober 2012 - 07:33 #4
Jeg har faktisk både tænkt på singleton pattern og måske Strategy pattern, men tror ikke strategy vil hjælpe.

Dog tænkte jeg at singleton var lidt omstændigt for noget, der lyder ret simpelt.

Jeg skal bare sikre mig at værdien af det jeg vil holde, kan klare flere tråde. Kommer brugen af min applikation fra en anden vej, så skal der være to 'sessioner', hvor to forskellige værdier holdes på henholdsvis, hver deres session.
Avatar billede CodingJoe Nybegynder
10. oktober 2012 - 10:25 #5
Hvad siger i til denne meget simple singleton? Den skal være threadsafe...jeg er ikke helt sikker på hvad object Lock bruges til...det er nok for at opretholde en thread safety:

public static class Singleton
    {
        static Vaerdi _instance;
        static readonly object Lock = new object();

        public static Vaerdi HentMinVaerdi
        {
            get
            {
                lock (Lock)
                {
                    if (instance == null)
                    {
                        instance = new Vaerdi();
                    }
                  return instance;
                }
            }
        }
Avatar billede Syska Mester
10. oktober 2012 - 12:44 #6
Din naming synes jeg er mindre heldig ... hold dig til engelsk, det gør alle glade der skal se din kode fremover.

Specielt fordi vi på dansk netop har ÆØÅ.

HentMinVaerdi burde hedde MinVaerdi ... hence du du kalder den som:

var vaerdi = Singleton.MinvVaerdi;

er det jo implicit angivet du vil hente den.

ThreadSafe er overstående ikke ... men du burde nemt kunne google en løsning. Problemet er at hvis Vaerdi klassen har properties, kan de jo ændres af alle dem som henter klassen.
Avatar billede arne_v Ekspert
10. oktober 2012 - 15:21 #7
Det der er ikke en singleton.

public class MySingleton
{
    private static MySingleton _instance;
    private static readonly mylock = new object();
    private int iv;
    private string sv;
    private MySingleton()
    {
          iv = 123;
          sv = "ABC";
    }
    public static MySingleton Instance
    {
          get
          {
              lock(mylock)
              {
                    if(_instance == null)
                    {
                          _instance = new MySingleton();
                    }
              }
          }
    }
    public int IV { get { return iv; } }
    public string SV { get { return sv; { }
}
Avatar billede arne_v Ekspert
10. oktober 2012 - 15:22 #8
Med en lock yderst i get instance property er den thread safe.
Avatar billede Syska Mester
10. oktober 2012 - 16:08 #9
Hvis man ikke skal kunne ændre sine værdier, så kan man jo ligeså godt lave en static properties.
Avatar billede arne_v Ekspert
10. oktober 2012 - 16:30 #10
Ikke helt.

Et singleton object er faktisk et objekt som kan sendes som et saadant.

Og det kan ogsaa implementere interfaces etc..
Avatar billede arne_v Ekspert
10. oktober 2012 - 16:33 #11
Man kunne ogsaa tilfoeje set til de properties.

Men saa er det at det begynder at vaere lidt tricky med, hvor vaerdierne bliver sat.
Avatar billede Syska Mester
10. oktober 2012 - 16:50 #12
#10
Ja, men så vil du måske også rende ind i ThreadSafe issues.

#11
Netop ... derfor jeg skrev det højst sandsynligt ikke ville være threadsafe.

Men jeg er helt enig ...
Avatar billede arne_v Ekspert
10. oktober 2012 - 17:04 #13
En af fordelene ved at have et objekt er at man faktisk kan bruge lock paa det!

MySingleton mys = MySingleton.Instance;
lock(mys)
{
  mys.SV = "DEF";
}

...

string sv;
MySingleton mys = MySingleton.Instance;
lock(mys)
{
  sv = mys.SV;
}
Avatar billede CodingJoe Nybegynder
10. oktober 2012 - 17:58 #14
Tak for alle inputs.

#7 Jeg har behov for at sætte værdien udefra som noget indledende i min kode, det kan evt. ske under instansieringen.

Arne kan du også lave et hurtigt eksempel på brugen af din singleton?

@Buzz det kode jeg har skrevet ind er ikke en-til-en med navngivningskonventioner, så det har blot været noget hurtigt kode.
Avatar billede arne_v Ekspert
10. oktober 2012 - 18:03 #15
#13 - lock:

MySingleton mys = MySingleton.Instance;
mys.SV = "DEF";

...

MySingleton mys = MySingleton.Instance;
string sv = mys.SV;
Avatar billede arne_v Ekspert
10. oktober 2012 - 18:03 #16
Du skal nok finde nogle andre navne end MySingleton, IV og SV.
Avatar billede CodingJoe Nybegynder
10. oktober 2012 - 18:05 #17
Naturligvis :)
Avatar billede CodingJoe Nybegynder
10. oktober 2012 - 18:20 #18
Har du testet koden i #7?

Der er et par ting der ikke helt er på plads.

Fx mangler der er et return statement :(
Avatar billede CodingJoe Nybegynder
10. oktober 2012 - 18:21 #19
AHh fik det fikset...der manglede nogle krøllede paranteser...
Avatar billede CodingJoe Nybegynder
10. oktober 2012 - 18:23 #20
Jeg har tilrettet min kode stærkt inspireret af #7:

public class MySingleton
    {
        private static MySingleton _instance;

        private static readonly object laas = new object();

        private string vaerdi;

        private MySingleton()
        {
        }

        public static MySingleton Instance
        {
            get
            {
                lock (laas)
                {
                    if (_instance == null)
                    {
                        _instance = new MySingleton();
                    }
                }
            }
        }

        public string Vaerdi
        {
            get
            {
                return vaerdi;
                {
                }
            }
        }
    }
Avatar billede arne_v Ekspert
10. oktober 2012 - 18:42 #21
Jeg tror at jeg var kommet til at taste { hvor det skulle være }.
Avatar billede CodingJoe Nybegynder
10. oktober 2012 - 18:44 #22
Ok, men ovenstående er min lille demo kode inspireret af den. Jeg prøver lige at lave et eksempel på brugen af den.

Håber du ser ovenstående som en korrekt singleton.
Avatar billede CodingJoe Nybegynder
10. oktober 2012 - 18:47 #23
class Program
    {
        static void Main(string[] args)
        {
            var a = MySingleton.Instance;
            a.Vaerdi = "Hallo";
        }
}

Det kan være jeg skal have det skåret ud i pap, men ovenstående er nok ikke måden, jeg skal sætte min værdi på?
Den siger ihvertfald, der ikke er nogen setter på min property. :(
Avatar billede arne_v Ekspert
10. oktober 2012 - 19:03 #24
bortset fra en overfloedig { } ser den OK ud.
Avatar billede arne_v Ekspert
10. oktober 2012 - 19:04 #25
Hvis du vil sette skal du naturligvis tilfoeje en set.

Men som sagt: hvis det er muligt kun at sette i constructor (f.eks. laese ind fra config fil der) saa er det godt.
Avatar billede CodingJoe Nybegynder
10. oktober 2012 - 19:05 #26
Ja, den fik jeg faktisk fjernet. Men har stadigvæk problemer med at sætte min værdi.

class Program
    {
        static void Main(string[] args)
        {
            var a = MySingleton.Instance;
            a.Vaerdi = "Hallo"; <---- Does not compute :(
        }
}
Avatar billede CodingJoe Nybegynder
10. oktober 2012 - 19:07 #27
Det vil jeg faktisk gerne, og det er faktisk en værdi fra en config...men ok jeg vil gerne sætte den som en del af min contructor...så således altså:


  private MySingleton(string vaerdi)
        {

        }
Avatar billede CodingJoe Nybegynder
10. oktober 2012 - 19:10 #28
Damn, så forstod jeg det du mente... :)

Nej, det kan jeg ikke. Jeg kan desværre ikke læse fra en config fil inde i min contructor...det er en værdi, der faktisk bestemmer, hvilken del af min configuration, jeg skal bruge.
Avatar billede CodingJoe Nybegynder
10. oktober 2012 - 19:14 #29
public string Vaerdi { get; set; }

Det blev ovenstående...men så kan man vel til enhver tid overskrive den vaerdi, jeg allerede har haft skrevet. Det er vel også ok, da det er noget jeg / en udvikler explicit vælger at gøre...
Avatar billede CodingJoe Nybegynder
10. oktober 2012 - 19:41 #30
Jeg har noget der funker....og det ser godt ud....endnu en gang tak for at sætte mig ind i et pattern :)
Avatar billede CodingJoe Nybegynder
10. oktober 2012 - 21:42 #31
Hmmmm jeg tvivler lidt på om det virkelig er en singleton, jeg har brug for. Mit indlæg #5, gav faktisk også det jeg havde brug for. En statisk måde at sætte og læse en variabel på. Tænker på at skrælle lock delen væk og bruge resten.

HVad siger I?
Avatar billede arne_v Ekspert
10. oktober 2012 - 22:31 #32
#5 sikrer ikke at der kun er en instans af Vaerdi klassen
Avatar billede CodingJoe Nybegynder
11. oktober 2012 - 00:27 #33
Ok.

Smid bare et svar ind Arne. Du er en Jedi Master...hvor jeg sikkert ikke engang er en padawan endnu... :)

Tak for hjælpen.
Avatar billede arne_v Ekspert
11. oktober 2012 - 00:43 #34
svar
Avatar billede CodingJoe Nybegynder
11. oktober 2012 - 07:35 #35
Hvornår bliver lock'en egentlig released?
Avatar billede arne_v Ekspert
11. oktober 2012 - 14:03 #36
ved dens }
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester