Avatar billede simsen Mester
15. august 2010 - 13:35 Der er 19 kommentarer og
2 løsninger

Sætte en værdi i en anden projekt

Hejsa,

Jeg har følgende projekter i en solution:

Portal
Denne indeholder min DBUtility - altså her jeg sætter min datasets/datatables osv. op i forskellige metoder.

Portal.Library
Denne indeholder min DAL - altså metoder til at hente/indsætte/opdatere/slette i databasen.
Jeg laver her en reference til Portal projektet og bruger metoderne fra Portal her.

Portal.Web
Det er så selve hjemmesiden/grafiske layout, hvor jeg bruger metoder fra Portal.Library.
Jeg laver her en reference til Portal.Library.

Nu er det så, jeg frygtelig gerne vil sætte en værdi i Portal.Web, som skal bruges i Portal (til at bestemme om, den skal cache de tabeller, der hentes fra databasen eller ej. I Portal vil jeg så spørge på den værdi for at bestemme dette....

Men jeg tør ikke bare tilføje en reference i Portal til Portal.Web - for aner jo ikke hvad der sker....Vil programmet køre i loop eller hvad...

Eller hvordan gør jeg det
Portal
|
Portal.Library
|
Portal.Web

og så

Portal.Web
|
Portal

En af metoderne i Portal der skal have en værdi fra Portal.Web ser ud som følgende:

public DataSet GetDataSet(string query, string cacheName, DateTime cacheTime, CommandType commandtype)
        {
            _command.CommandText = query;
            _command.CommandTimeout = _commandTimeout;
            _command.CommandType = commandtype;

            SqlDataAdapter adpt = new SqlDataAdapter(_command);

            DataSet dsCached = null;
            DataSet ds = new DataSet();

            //Her jeg vil hente en værdi fra Portal.Web

            OnCachedItemRemoved = new CacheItemRemovedCallback(this.CachedRemovedCallback);

            //Denne skal så testes op imod værdien fra Portal.Web
            dsCached = System.Web.HttpContext.Current.Cache.Get(cacheName) as DataSet;

            if (dsCached == null)
            {
                try
                {
                    if (_connection.State == System.Data.ConnectionState.Closed)
                    {
                        _connection.Open();
                    }
                   
                    adpt.Fill(ds);
                    //Denne skal så testes op imod værdien fra Portal.Web
                    System.Web.HttpContext.Current.Cache.Insert(cacheName, ds, null, cacheTime, TimeSpan.Zero, CacheItemPriority.Default, OnCachedItemRemoved);
                }
                catch (Exception)
                {
                    throw;
                }
                finally
                {
                    _command.Parameters.Clear();

                    if (_connection.State == System.Data.ConnectionState.Open)
                    {
                        Dispose();
                    }
                }
            }
            else
            {
                ds = dsCached;
            }

            return ds;
        }

mvh
simsen :-)
Avatar billede heinzdmx Nybegynder
15. august 2010 - 19:21 #1
Du kan refere til et projekt der allerede har en reference til projektet.

Dvs:

main (referere til sub)  -> sub := main kan tilgå sub

sub (refere main) -> main (refere sub) := vil give en løkke som ikke er muligt. Det giver en compile error.

Af mulige løsninger:

- Et helt andet projekt der kan indeholde data, som både sub og main har tilføjet referencer til
- Tilføj værdien i sub, så skal du bare have main til at sætte værdien i sub

Den sidste er nok den mest anvendelige, hvis det kun lige er den ene variabel du er ude efter
Avatar billede Syska Mester
15. august 2010 - 21:43 #2
Hvis dine referencer skal det loop er det fordi opdelingen efter min mening ikke er speciel god, hence det problemer du får.

Hvis du fra dit Portal lag vil bruge en type fra dit Web lag, hører den type så ikke reelt set hjemme i dit Portal lag ? ( bare min første tanke )

mvh
Avatar billede simsen Mester
16. august 2010 - 01:19 #3
Mit problem er ja ja biiiig surprise.......min caching....

Den har jeg jo sat i mit portal lag.

Nu ville jeg så frygtelig gerne, at hvis UnoEuro skrev til mig (når sitet er i produktion), at det var et problem...det bruger for meget ram, at jeg så kunne via codebehind kunne sætte en værdi, der ændrede det til ikke at cache.... Så jeg ville blive fri for at skulle builde og publish'e én gang til.....

Så ja det er ren og skær magelighed fra min side, at jeg gerne vil kunne sætte en værdi i web delen som så slog igennem opad :-)
Avatar billede simsen Mester
16. august 2010 - 01:24 #4
heinzdmx

Jeg forstår ikke helt denne her:
Tilføj værdien i sub, så skal du bare have main til at sætte værdien i sub

Gider du forklare mig den i forhold til mine projekter som er følgende

Portal -> Portal.Library -> Portal.Web
Avatar billede Syska Mester
16. august 2010 - 08:29 #5
Vis noget kode ...

Det må være stadig være fordi din type er i dit web lag i stedet for dit portal lag. Hvorfor skulle dit portal lag eller skulle kende til dit web lag? Hvis det ikke var for at vide hvad for typer der var i det lag.

mvh
Avatar billede simsen Mester
16. august 2010 - 11:16 #6
Hmmmmm

Aner ikke om det er hvad I har prøvet at fortælle mig - men har valgt at smide en ny parameter med en i de 2 metoder i Portal laget og så tilføje den parameter heeeeeele vejen ned, hvor jeg så i mit web lag definerer om den skal være true/false.... *suk* Mega meget arbejde....

Hvis én af jer, har forsøgt det - så smid et svar og I får jeres points :-)
Avatar billede Syska Mester
16. august 2010 - 11:34 #7
Du bliver nød til at poste noget mere kode så ...

Problemet som jeg ser det, er at du prøver at afkoble din solution ved at lave flere projekter, på den måde kan du også nemmere bruge dit Protal lag i andre projekter, men hvis du i dit Portal lag, kræver at den skal kunne se dit Web lag, så kan det jo ikke genbruges, hvis du ville lave en Windows Client.

Håber du kan følge ideen, og hvorfor du ikke skal gøre som du prøvede på :-)

mvh
Avatar billede simsen Mester
16. august 2010 - 12:35 #8
buzzzz

Jeg tror vi går forbi hinanden.....

Jeg har nu ændret min metode, som jeg viste i start indlægget og brugt de sidste par timer til at rette min kode nedad i systemet, så den tager en parameter(værdi) mere med ind i metoden, som så afgør om den skal cache eller ej.

public DataSet GetDataSet(string query, string cacheName, DateTime cacheTime, CommandType commandtype, bool IsPortalCached)
        {
            _command.CommandText = query;
            _command.CommandTimeout = _commandTimeout;
            _command.CommandType = commandtype;

            SqlDataAdapter adpt = new SqlDataAdapter(_command);

            DataSet dsCached = null;
            DataSet ds = new DataSet();

            if (IsPortalCached)
            {
                OnCachedItemRemoved = new CacheItemRemovedCallback(this.CachedRemovedCallback);
                dsCached = System.Web.HttpContext.Current.Cache.Get(cacheName) as DataSet;
            }

            if (dsCached == null)
            {
                try
                {
                    if (_connection.State == System.Data.ConnectionState.Closed)
                    {
                        _connection.Open();
                    }
                   
                    adpt.Fill(ds);
                    if (IsPortalCached)
                    {
                        System.Web.HttpContext.Current.Cache.Insert(cacheName, ds, null, cacheTime, TimeSpan.Zero, CacheItemPriority.Default, OnCachedItemRemoved);
                    }
                }
                catch (Exception)
                {
                    throw;
                }
                finally
                {
                    _command.Parameters.Clear();

                    if (_connection.State == System.Data.ConnectionState.Open)
                    {
                        Dispose();
                    }
                }
            }
            else
            {
                ds = dsCached;
            }

            return ds;
        }

Det eneste jeg ville, var at jeg frygtelig gerne ville have haft sat værdien udenfor metoden (så jeg var fri for at ændre samtlige metoder, der bruger ovennævnte metode - ja ja jeg ER doven *griner*)
Avatar billede janus_007 Nybegynder
16. august 2010 - 12:36 #9
Vi må da ikke håbe det skal bruges til andet end inhouse.

simsen-> en god idé er altså at bruge noget tid på at forstå lag-principperne og nogenlunde følge design patterns. Det vil gøre koden nemmere at forstå og vedligeholde.
Avatar billede janus_007 Nybegynder
16. august 2010 - 12:38 #10
btw...

Istedet for:
catch (Exception)
        {
          throw;
        }

kan du gøre sådan her:
catch
{
  throw;
}

Så undgår du en warning :)
Avatar billede simsen Mester
16. august 2010 - 12:40 #11
For at uddybe ovennævnte....

Jeg ville gerne i den klasse (DBUtility.cs) have sat en public field:

public bool IsPortalCached { get; set; }

I min metode i Portal, ville jeg så hente IsPortalCached for at afgøre om den skal cache eller ej.....

Og så i min Portal.Web del - ville jeg have sat IsPortalCached til enten true eller false i f.eks. PageLoad i MasterPage filen.

Så hver gang at jeg brugte metoden, ville den vide om IsPortalCached var sat til true/false....
Avatar billede simsen Mester
16. august 2010 - 12:44 #12
janus_007

mht. exception, har jeg bare ikke fået thrown de korrekte dele endnu - det kommer :-)

Tak for din kommentar.....
Vi må da ikke håbe det skal bruges til andet end inhouse.

Den hjælper mig da enormt meget. Jeg skriver herinde, for at få hjælp til at lære......ikke for at blive nedgjort :-)
Avatar billede heinzdmx Nybegynder
16. august 2010 - 12:44 #13
Det ville også have været muligt. Hvis du tilføjede en metode i dit Portal.Library der satte værdien, som du kunne kalde fra Portal.Web

Portal.Library skal så sætte værdien i din Portal
Avatar billede heinzdmx Nybegynder
16. august 2010 - 13:14 #14
Det er netop det.

Portal.Web sender parameter til Portal.Library -> sender paramter til Portal der udfører koden.

Som Buzzz også siger, sørg for at når du deler dine projekter på i de dele, så skal du også sørge for at din Portal ikke er afhængig af Web -delen, så du får noget der kan bruges på andre måder.

Sørg for at dit under bibliotek indeholder de metoder der skal bruges, og de bliver sat ved et metode kald.

Så du får f.eks.:

Portal.Web
{
Portal.Library.update(bool cache)
}

Portal.Library
{
Portal.update(bool cache)
}
Portal
{
update(bool cache)
{
kør din kode
}
Avatar billede simsen Mester
16. august 2010 - 17:10 #15
buzzzz og heinzdmx

Vil I venligst lægge et svar, så skal I få de points, der er udlovet og tak for hjælpen.....Både i den her tråd og andre :-)
Avatar billede heinzdmx Nybegynder
16. august 2010 - 17:26 #16
Svar her :)
Avatar billede janus_007 Nybegynder
16. august 2010 - 17:47 #17
hej simsen... synes da ikke jeg har nedgjort dig, men ellers så tag imod min undskyldning.

Jeg synes ikke løsningerne er elegante og nu skriver du at du gerne vil lære :)

Du har stadigvæk en binding til web igennem System.Web.HttpContext.Current.Cache.Insert(cacheName, ds, null, cacheTime, TimeSpan.Zero, CacheItemPriority.Default, OnCachedItemRemoved);

Så... om du sætter en variabel igennem Library eller ej er et fedt.
Og udover det er det altså fuldt tilladt at skrive sådan her:
public bool IsPortalCached { get; set; }

...og så sætte den variabel fra web-lib-db, men det er httpcontexten i dit dal der ikke er ok!

Det som du måske skulle overveje var at lave en Cache-lag og så sætte det imellem dal og web, på den måde vil det også være nemmere at lave specielle regler for cachen + at du har et bedre overblik :)
Sådan at cachelag må naturligvis gerne have kendskab til web og dal :)
Avatar billede simsen Mester
16. august 2010 - 19:22 #18
janus_007

Tak for dit sidste indlæg......

Jeg har rent faktisk ikke tænkt over, at jeg binder web indhold i den der  System.Web.HttpContext.Current.Cache.Insert i min Portal, før dit sidste indlæg. Jeg er fuldstændig grøn mht. caching og har så "bare" slavisk fuldt de tutorials jeg har googlet mig frem til.

Nu gør det ikke så meget i det her tilfælde, da det jeg er igang med altid kun vil være web baseret...

Mht. at sætte bool - så forsøgte jeg det faktisk først - men den slog ikke igennem. Altså jeg satte bool IsPortalCached {get, set} i Portal i DBUtility class og kunne så også lave en isPortalCached = true i Portal.Web - men når jeg så forsøgte at køre en af metoderne i DBUtility class, var IsPortalCached altid false....

Mht. Cache-lag (og fremtidig brug af min Portal projekt) - forstår jeg dig ret: At jeg skal lave et nyt projekt. I det nye projekt lave først metoder, der indsætter/henter i cachen - og så ellers lave metoder for hver metode i DAL, der binder metoden insert cache og hentning fra DAL eller hentning fra Cache ind i web delen?
Avatar billede janus_007 Nybegynder
16. august 2010 - 20:10 #19
At sætte isPortalCached skal kunne lade sig gøre, du skal sikre dig at du gør det på samme instans af Portal, ellers skal du lave den static!

altså.
public static bool isPortalCached{get; set;} , så kan du sætte den hvorfra og hvornår du har lyst.

Ja du har forstået det korrekt, et nyt projekt. Nu er du ny og sådan... og det kan måske være en for stor mundfuld, men prøv at kigge lidt på generics, de vil være en stor hjælp i sådan et cachelag. Hvis du bruger det generiske kan du snildt anvende dit projekt/ assembly i andre løsninger. Langsomt vil du få opbygget en codebase som gør det nemmere for dig at udvikle.

Her er en god beskrivelse af generisk caching :)
http://johnnycoder.com/blog/2008/12/10/c-cache-helper-class/

Ellers bare spørg :)
Avatar billede Syska Mester
16. august 2010 - 21:10 #20
lav et ICache interface som har de metoder du vil bruge.

Nu kan du lave en implementering af ICache og sende den med som parameter til dit Portal/DB lag ... måske også noget logik som afgør hvad der skal caches, som automatisk bliver kørt i din Add Method, der er mange muligheder.

IoC og DI patterns.
Avatar billede Syska Mester
16. august 2010 - 21:24 #21
svar
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