Avatar billede ibleif Nybegynder
25. januar 2005 - 12:32 Der er 73 kommentarer og
3 løsninger

ObjektModel (og Patterns) i ASP.NET

Hej Alle..

Jeg skal til at lave en lidt større ASP.NET applikation, og er blevet lidt træt af den "typiske" webmetode, der ligger op af transactionscripting, og vil nu gerne igang med at bruge noget mere lagdelt arkitektur.

Jeg vil høre om nogen har erfaringer med at bruge andre mønstre i deres web-udvikling? Måske ikke direkte en stor forkromet domain-model, men måske andre gode? (Jeg har en rimelig god teoretisk viden omkring patterns, bl.a. en del af GoF´s og Fowlers) - så håber vi kan tage en god diskussion her.

Glæder mig til at høre hvad I eksperter derude har at sige.

// Ibleif
Avatar billede arne_v Ekspert
25. januar 2005 - 12:40 #1
Jeg er ikke sikker på hvad spørgsmålet er.

MS ligger med ASP.NET meget op til opdeling i lag: præsentation,
forretnings logik og data adgang.

.NET klasserne bruger diverse patterns.

Din kode bør sikkert også bruge diverse patterns.

Men det viste du jo sikkert godt.
Avatar billede ibleif Nybegynder
25. januar 2005 - 12:58 #2
Ok.. måske min forklaring er lidt henne i hegnet..

Altså.. indtil videre har jeg når jeg har lavet ASP.NET applikationer gjort således, at hver gang jeg har skulle vise noget data, så har jeg igennem en DB-facade hentet en datatable, som jeg så har vist i GUI enten via databindning eller ved selv at udskrive det så det passede. Når jeg så har skulle opdatere har jeg genereret nogle UPDATE eller INSERT SQL-statements, som jeg så har fået eksekveret igennem min DB-facade.

Nu har jeg så de sidste par dage gået med tanken om at lave det sådan lidt mere som jeg kender fra "alm. applikationsudvikling" - hvor jeg tænkte på at lave nogle domæneklasser. F.eks. En "Bruger","Nyhed" eller en "Kommentar" klasse, som jeg så ville lave en Mapper klasse til, således at ved en opdatering kunne jeg kalde min mapper, og den ville sørge for at opdatering eller indsættelsen hvis det var et nyt objekt.

Det er sådan set det jeg gerne vil have noget feedback på, eller en lille snak ok! :-)

Håber det forklarer det bedre.

// Ibleif
Avatar billede arne_v Ekspert
25. januar 2005 - 13:02 #3
Det du foreslår bruges skam meget.

Både med:
  - egen håndkodet gem og hent kode
  - færdige biblioteker til gem og hent
  - tools som genererer kode til hele eller dele af klasserne
Avatar billede burningice Nybegynder
25. januar 2005 - 13:05 #4
det lyder da som en simpel O/R-mapper ? Well, ikke fordi at sådan en er simpel at lave, men er meget simpel at bruge. Der findes forskellige O/R-mappere rundt om på nettet, arne har vist sin favorit, kan ikke lige huske hvad den hedder.

Selv har jeg udviklet en mere specifik-løsning hvor jeg har et IDbObject-inteface som jeg kan lade mit object implementere hvis at det skal kunne gemmes i en database/xml-fil. Dette interface indeholder nogle metoder som svarer til Update, Insert, Select og Delete, og de bliver automatisk kaldt af det underliggende system når at der er sket ændringer i objectet. Altså ikke noget man som udvikler af selve UI/præsentations-laget skal tænke på.
Avatar billede ibleif Nybegynder
25. januar 2005 - 13:08 #5
Jeg skal så have valgt et passende "Domain Logic Pattern" - hvis vi lige skal tage lidt udgangspunkt i Fowler, men er det muligt (og evt. klogt?) at lave f.eks. en Domain Model i en webapplikation?

// Ibleif
Avatar billede arne_v Ekspert
25. januar 2005 - 13:08 #6
NHibernate

Jeg har nu aldrig brugt det, men udbredelsen af Hibernate gør at jeg har meget
tillid til produktet.
Avatar billede arne_v Ekspert
25. januar 2005 - 13:09 #7
WEB applikation burde skrives web APPLIKATION

:-)

det er altså en applikation ligesom alle andre
Avatar billede ibleif Nybegynder
25. januar 2005 - 13:14 #8
Ok - Det er selvfølgelig rigtigt nok. :-)

Ved ikke hvorfor jeg altid har set det som værende "forskellige" ting. Dvs. som en "in-memory" kopi af min logik, så ville man bare loade det ind i en Application-Variabel ?

// Ibleif
Avatar billede ibleif Nybegynder
25. januar 2005 - 15:25 #9
Hvis nogen har nogle gode links eller noget.. så må de meget gerne bidrage med det! :-) Vil gerne læse mere om det!

Her kommer så det klassiske spørgsmål.. hvor mange objekter er det klogt at holde i hukommelsen?

// Ibleif
Avatar billede burningice Nybegynder
25. januar 2005 - 15:37 #10
så mange du har brug for... og hvis det kniber med hukommelsen, så smid nogle flere ram i maskinen :P

Jeg har personligt været ude for under udviklingen af en webshop, og jeg endte med at loade alle produkterne op i databasen for at få perfomancen til at være acceptabel. Problemet lå i at hver produkt bestod af så mange underkomponenter at det tog for lang tid at generere et object af produktet hver gang det skulle vises.

Jeg synes ikke man skal være for nærig med sådan noget. Har man brug for at gemme noget i hukommelsen, så gør det sq. Sådan noget som Cache er da også Gates's gave til os udviklere, så at lade være med at bruge det for "ååh, det bruger for meget hukommelse"... det er noget crap.
Avatar billede arne_v Ekspert
25. januar 2005 - 15:43 #11
Afhænger jo lidt af konteksten.

Hvor meget fylder ens data. Jeg er helt enig med cf i at til normale
ting så smider man bare 512 MB mere i maskinen - det koster ikke meget.
men måler man ens data i TB, så bliver, man nødt til at revurdere ens
cache strategi.

Hvad er sandsyneligheden for at data skal bruges igen snart. Eller
hvad bliver cache hit rate. Selvfølgelig kun relevant hvis man ikke
gemmer alt.

Krav til data integritet og valget mellem writeback og writethrough.
Avatar billede ibleif Nybegynder
25. januar 2005 - 16:05 #12
- Tak for jeres svar...

cyberfessor: Hvordan opbevarer du så det i hukommelsen? I en "Application-variabel" ??

// Ibleif
Avatar billede christian Nybegynder
25. januar 2005 - 16:16 #13
Jeg ville helt klart kigge efter en OR-mapper, det er ikke blevet så stort i Danmark endnu (hvorfor ved jeg ikke).

En OR-mapper bygger på et godt database design.

Til dit første projekt vil jeg klart anbefale Wilson ORMapper http://www.ormapper.net
Den er ret nem at gå til forhold til de andre.
Du kan se hvordan den fungere her:
http://www.ormapper.net/Examples/
Der findes også mere læsestof om hans ORMapper på hans website http://www.wilsondotnet.com
Den koster 50$

Andre OR-mappers:
http://www.evaluant.com/en/solutions/dtm/default.aspx
http://nhibernate.sourceforge.net/
http://www.thona-consulting.com/content/products/entitybroker.aspx

Thona consulting har en rigtig god forklaring om hvorfor MS/VS.NET stadard måden er skod og hvorfor ORMapper bare er sagen
Desvære skal man være oprettet som bruger (gratis) for at downloade PDF filen
http://www.thona-consulting.com/content/forms/download.aspx

Til sidst er det lidt weblog læsning her:
http://geekswithblogs.net/sbellware/category/1026.aspx
Avatar billede burningice Nybegynder
25. januar 2005 - 16:19 #14
Application["noget"] = mitObject;
mitObject = (MitObject)Application["noget"];

Session, Cache og Application er de eneste tre muligheder du har for at gemme noget du kan få fat i igen. Ved ikke helt hvad du lægger i ordet "Application-variabel", men ja... hvis du skal gemme noget alle skal have fat i skal det i applikation. Ting der kun er gældende for den enkelte session skal i.. ja, session. Cache er lidt ligesom Application, men har nogle najs features som timeout, events og filovervågning.
Avatar billede christian Nybegynder
25. januar 2005 - 16:25 #15
Det burde måske nævnes at en ORMapper sørger for caching.
Og der er lazy-loading på relationer altså:
Bruger br = ORmapper.Get(TypeOf(Bruger), id);
string navn = br.Navn; // navn er hentet
SpoergsmaalListe liste = br.Sporgsmaal; // Lazy-loading, først nu hentes alle spørgsmål ud som tilhører brugeren

Documentation fra thona-consulting, får man vist kun hvis man downloader produktet fra dem... hvis du smider en e-mail skal jeg sende PDF'en (800KB) til dig
Avatar billede ibleif Nybegynder
25. januar 2005 - 16:33 #16
ibleif [@] hotmail prik com

- Send gerne... :-)

// Ibleif
Avatar billede ibleif Nybegynder
25. januar 2005 - 16:41 #17
Lazyloading var ellers en af de ting jeg havde overvejet selv at lave, men det kunne da være at man skal skulle overveje sådan en OR-mapper!

// Ibleif
Avatar billede arne_v Ekspert
25. januar 2005 - 16:44 #18
Microsoft har også et O/R mapping tool undervejs kaldet "Object Spaces".
Avatar billede christian Nybegynder
25. januar 2005 - 16:48 #19
pdf'en er sendt..

Noget af det som jeg syntes kan være lidt skod, når man udvikler sit eget system er sådan noget som:
ProfilSet profiler = bll.HentProfilerSomErIndenForMinOgMaksSletningdatoOgAktive("2005.01.01", "2005.02.02", false);
hvor at bll'en så kalder videre til min dal, hvor den så måske er lidt mere generisk.
Her er det rart med en ORMapper hvor man kan angive sine kritier på forskellige måder, object måden er OPath som du kan google på (wilsons understøtter vist ikke OPath)
Avatar billede arne_v Ekspert
25. januar 2005 - 16:51 #20
Og O/R mapping er altså ikke en sølv kugle.

Det er et godt værktøj til at få en pæn OO domain model ud af sine R databaser.

Men i hænderne på en ukyndig kan:
  - performance gå helt i bund
  - koden blive mere ulæselig end den gode gamle SQL/DataReader/list of objects
Avatar billede christian Nybegynder
25. januar 2005 - 16:54 #21
Der er ingen tvilv om at Object Spaces kommer til at dominere markedet, men desvære er det udskudt gang på gang... det sidste var vist at det først ville komme med deres nye filsystem

Wilson har bygget sin OR-mapper op omkring Object Spaces modsat mange af de andre

En wilson artikel om Object Spaces :-)
http://aspalliance.com/articleViewer.aspx?aId=248&pId=
Avatar billede christian Nybegynder
25. januar 2005 - 16:56 #22
Jeg kan ikke sende til dig:
Diagnostic-Code: smtp;552 5.2.2 This message is larger than the current system limit or the recipient's mailbox is full. Create a shorter message body or remove attachments and try sending it again.
Avatar billede arne_v Ekspert
25. januar 2005 - 16:56 #23
Og en af de lidt trælse ting ved O/R mapping tools er et stort set hver
eneste af dem har sit eget query language. Og ja de ligner hinanden meget,
men er netop ikke identiske.
Avatar billede christian Nybegynder
25. januar 2005 - 16:56 #24
Skal jeg sende dig en GMail invitation med det samme, så skulle du vist ikke løbe tør for plads :-)
Avatar billede ibleif Nybegynder
25. januar 2005 - 16:57 #25
Så skulle der være plads igen... dumme hotmail og alt det spam! :-(

// Ibleif
Avatar billede ibleif Nybegynder
25. januar 2005 - 16:59 #26
christian: Ville da være lækkert!

// Ibleif
Avatar billede ibleif Nybegynder
26. januar 2005 - 19:06 #27
Hi alle!

Nu har jeg kigget lidt videre på det, og har besluttet mig for, at mit nye projekt skal bruge en fuld "domain model", men vil gerne have planlagt hele min applikation inden jeg starter på den! (Hvilket nok er normal god praksis *g*)

Mit næste problem er så at jeg skal vælge et "Data Source" mønster. Jeg har kig på "Data Mapper", da jeg ved at jeg vil få n <-> n forbindelser imellem nogle af mine objekter, som vel så vil ende som en "Association Table Mapping", og det er mit indtryk af f.eks. "Table Data Gateway" og "Row Data Gateway" har som udgangspunkt at objekterne i modellen afspejler netop 1 tabel/row ?? Vil nogen kommentere på dette? og er det evt. nogen der har en implementation liggende til .NET, som man kunne bruge som inspiration?

I forbindelse med dette, så tænker jeg også på hvordan jeg skal holde min Domain Model konsistent med min database. (Hvis f.eks. systemet crasher) Vil gerne have nogle foreslag her.. ?? Tænker det er lidt vildt, hvis man skal sørge for at køre en update sql igennem sin mapper hver gang en property på et objekt bliver ændret?

Glæder mig til at få lidt hjælp/kommentar/inspiration...

// Ibleif
Avatar billede ibleif Nybegynder
27. januar 2005 - 07:45 #28
Er der virkelig ikke nogen der vil kommentere på dette?! :-(

- nå, så hvis folk vil ligge et svar, så vi kan få lukket efter os. Så må jeg oprette et nyt spørgsmål.

// Ibleif
Avatar billede burningice Nybegynder
27. januar 2005 - 10:36 #29
konsistens er jo altid et problem... hvis du ikke vil gemme i realtime (så snart noget bliver ændret) må du lave en form for autosave. Når du sidder og skriver i word er der jo også risiko for at noget går tabt da den jo heller ikke gemme så snart du taster.

En anden mulighed er at implementere end CommitChanges-metode til dine Db-objecter så du kan gemme deres state efter en større ændring.

Ang. de andre ting kan jeg nok ikke hjælpe.
Avatar billede christian Nybegynder
27. januar 2005 - 10:44 #30
lidt point for mine indlæg kunne være lækkert
Avatar billede arne_v Ekspert
27. januar 2005 - 10:45 #31
Jeg kender intet til de mønstre du snakker om.

Din database er vel en del af implementerinten af din domain model. Men du mener
sikkert konsistens mellem in memory data strukturer og databasen. Hvis din
software kun skal køre på single node, så er det ret nemt at opnå med writethrough.
Hvis det er multinode, så er det meget sværere.
Avatar billede arne_v Ekspert
27. januar 2005 - 10:46 #32
svar fra mig
Avatar billede ibleif Nybegynder
27. januar 2005 - 10:49 #33
Cyberfessor: Må jeg spørge hvad du "normalt" gør?

- Vil gerne vente på arne_v... både hans mening og sådan at han kan få lidt point også!

// Ibleif
Avatar billede ibleif Nybegynder
27. januar 2005 - 10:51 #34
De mønstre jeg har omtalt fra en bog af "Martin Fowler" - troede det var generelle mønstre han havde deri.

// Ibleif
Avatar billede arne_v Ekspert
27. januar 2005 - 10:53 #35
Det tror jeg faktisk også at de er. Men bare ikke så almindeligt kendt som f.eks. GoF
patterns.
Avatar billede ibleif Nybegynder
27. januar 2005 - 11:03 #36
arne_v: Når du snakker single-node .. betyder det så i praksis bare 1 webserver?

// Ibleif
Avatar billede arne_v Ekspert
27. januar 2005 - 11:06 #37
Avatar billede arne_v Ekspert
27. januar 2005 - 11:07 #38
Det betyder en node i det tier vi kigger på.

Men hvis vi nu kigger på en browser--web app--database løsning, så betyder
det en enkelt web server.
Avatar billede burningice Nybegynder
27. januar 2005 - 11:20 #39
jeg har selv implementeret en CommitChanges() funktion der skriver ændringerne tilbage til min datastore igen. Denne kaldes der hvor at objectet er kaldet og der er lavet ændringer. Ved hjælp af durty-flag kan jeg så se hvilke data der er ændret siden sidst.

Eksempel:

User u = User.GetById(45);
u.LastLoggedIn = DateTime.Now;
u.CommitChanges();

Ang. de andre mønstre må jeg tilslutte mig arne og erkænde at jeg ikke umiddelbart har hørt om dem før.
Jeg bruger ikke selv en O/R-mapper, forestået som et tredieparts produkt. For jo, selvfølgelig mapper jeg mellem mine objecter og databasen, men det sker igennem kode jeg selv skriver/genererer.
Avatar billede ibleif Nybegynder
27. januar 2005 - 11:24 #40
Cyberfessor: ok, tak for det. Har et sidste spørgsmål, som I måske vil hjælpe med.

Jeg har i min applikation en opbygning, som kommer til at hedde en "User" klasse og en "Group" klasse. En User kan være tilknyttet mange grupper, og dermed også omvendt. Jeg har brug for at kunne gå begge veje, men ikke nok med det, så har hver User også forskellige rettigheder i de forskellige groups. Hvordan ville I modellere dette som Objekter og som nedenunder liggende database ?

Da jeg er bedst til at tænke hvordan det skal opbevares i dben, så tænker jeg her tabellerne:
User <-> Userrights <-> Groups

- men, hvordan ville I gøre det objekt mæssigt?

Ved godt det er et sidespring, og kan evt. oprette et andet spørgsmål?

// Ibleif
Avatar billede burningice Nybegynder
27. januar 2005 - 11:31 #41
nu har jeg kigget lidt på de forskellige patters beskrevet på http://www.martinfowler.com/eaaCatalog/index.html, og kan da godt nikke genkendende til dem, uden dog at have vist hvad de hed.

Jeg bruger selv Table Data Gateway for at kunne mappe mine objecter ned i database, og op igen, uden at smaske selve mit object til med sql-kode. Association Table Mapping er også meget anvendt.
Dog har jeg aldrig brugt noget der ligner Row Data Gateway, og har svært ved at se dens styrke i andet end NUnit-testning.
Avatar billede burningice Nybegynder
27. januar 2005 - 11:38 #42
jeg ville nok lave en slags facade hvori at man kan query på hvilke rettigheder en bruger har i en gruppe og ud af det få et Userrights-object retur.

User u = User.GetByName("Jakob")
Group g = u.Groups["Admins"];

UserRights right = UserRights.Query(u, g);
Response.Write(u.ToString() +" is "+ right.ToString() +" in the +" g.ToString());
// Jakob is admin in the Admins group
Avatar billede burningice Nybegynder
27. januar 2005 - 11:40 #43
det kan selvfølgelig også laves den anden vej

Group g = Groups.GetByName("Admins");
User u = g.Users["Jakob"];

UserRights right = UserRights.Query(u, g);
Response.Write(u.ToString() +" is "+ right.ToString() +" in the +" g.ToString());
// Jakob is admin in the Admins group
Avatar billede christian Nybegynder
27. januar 2005 - 11:45 #44
Jeg ville gøre det enten ved at oprette en UserSet og GroupSet klasse
De ville så bare indeholde et ArrayList som har objecterne i sig.

Din User klasse vil så indeholde
public GroupSet Groups
{
  get { return this.groups; }
  set { set this.groups; }
}

Typisk ville man kalde db relation tabellen UsersInGroups

Man kunne også lave en mere general object liste

Wilson har en rimlig god en... nedenståender er taget via Reflector som giver et lille overblik
public class ObjectList : ILoadOnDemand, IObjectSet, IObjectPage, IList, ICollection, IEnumerable
{
      // Methods
      internal ObjectList(Context context, Type objectType);
      internal ObjectList(Context context, ObjectQuery objectQuery);
      internal ObjectList(Context context, ObjectSet objectSet);
      internal ObjectList(Context context, SelectProcedure selectSP);
      public int Add(object entityObject);
      public void Add(object objectKey, object entityObject);
      public void Clear();
      public bool Contains(object entityObject);
      public void CopyTo(Array array, int index);
      public IEnumerator GetEnumerator();
      public object GetObject(object objectKey);
      public int IndexOf(object entityObject);
      public void Insert(int index, object entityObject);
      public void Remove(object entityObject);
      public void RemoveAt(int index);
      public void RemoveByKey(object objectKey);
      public void Resync();
      public override string ToString();

      // Properties
      public int Count { get; }
      private IList IList { get; }
      public bool IsFixedSize { get; }
      public bool IsLoaded { get; }
      public bool IsReadOnly { get; }
      public bool IsSynchronized { get; }
      public object this[int index] { get; set; }
      private ObjectSet List { get; }
      public Type ObjectType { get; }
      public int PageCount { get; }
      public int PageIndex { get; }
      internal ArrayList Removed { get; }
      public object SyncRoot { get; }

      // Fields
      private Context context;
      private ObjectSet list;
      private ObjectQuery query;
      private SelectProcedure selectSP;
      private Type type;
}
Avatar billede arne_v Ekspert
27. januar 2005 - 11:49 #45
database:

3 tabeller

in memory:

2 klasser

Det er jo faktisk hele essensen af forskellen mellem OO og R.
Avatar billede ibleif Nybegynder
27. januar 2005 - 11:52 #46
arne_v: Ja, det er jo netop mit problem. Jeg kan godt se at en rettighedsklasse ikke ville høre hjemme i modellering af logikken, men hvordan ville du så gøre det? Jeg kan ikke se hvordan man på en bruger, så ville gemme hans rettigheder til de forskellige grupper?

// Ibleif
Avatar billede arne_v Ekspert
27. januar 2005 - 11:56 #47
I databasen laver du en tabel som repræsenterer M:M relationen med 2 felter
soms ammen er pPK og FK til hver sin tabel.

I memoru har både User og group klasserne en liste som indeholder alle
henholdsvis groups og users.
Avatar billede ibleif Nybegynder
27. januar 2005 - 12:01 #48
Det vil sige, at en gruppe og en user vil få en collection til hver rettighed..?

// Ibleif
Avatar billede burningice Nybegynder
27. januar 2005 - 12:04 #49
"så har hver User også forskellige rettigheder i de forskellige groups"

ud fra dette vil tabellen have flere end 2 felter, da der også skal kunne beskrives hvilken rettighed brugeren har i den pågældende gruppe
og det vil heller ikke være nok at have

1) en liste over grupper brugeren er med i i User-objectet
2) en liste over brugere der er med i gruppen i Group-objectet

Der mangler den sidste information, der beskriver brugerens rolle i den pågældende gruppe, og der vil jeg mene at mit forslag opfylder det. Det implementer netop arne'ss forslag med at både User og Group har en liste over Groups og Users der hører til dem PLUS at man har mulighed for at få oplyst hvilken rolle brugeren har i gruppen.
Avatar billede ibleif Nybegynder
27. januar 2005 - 12:26 #50
Overvejer at lave en Collection på User, som bare indeholde alle de grupper han er med i .. og så lave 3 collections på Group klassen.. en AdminCollection, ModeratorCollection og UserCollection ...

Jeg tror at det er hvad Arne_v fisker efter? Ville dette ikke dække det?

// Ibleif
Avatar billede arne_v Ekspert
27. januar 2005 - 12:30 #51
Nej. Du laver 3 instanser af Group klassen Admin, Moderator og User. Hver af
disse indeholder en collection af deres users.
Avatar billede burningice Nybegynder
27. januar 2005 - 12:34 #52
træls hvis man gerne vil have en 4 gruppe med

:)
Avatar billede ibleif Nybegynder
27. januar 2005 - 13:38 #53
Jamen.. måske mit OO er blevet noget rustent, men jeg forstår ikke helt den løsning der arne_v!? Hvis gruppen er opdelt på 3 instanser, hvordan vil du så f.eks. hente en komplet liste over alle Users tilknyttet gruppen?

Tror jeg skal have noget skåret ud i en stykke bølgepap her?! :-)

// Ibleif
Avatar billede arne_v Ekspert
27. januar 2005 - 13:42 #54
instanser af klassen Group repræsenterer en enkelt gruppe

og dens collection indeholder alle brugere tilknyttet den gruppe
Avatar billede burningice Nybegynder
27. januar 2005 - 13:44 #55
Hmm... tror måske jeg ved hvad han mener

Group admins = Group.GetUsersByLevel(UserLevel.Admin);
Group moderator = Group.GetUsersByLevel(UserLevel.Moderator);
Group users = Group.GetUsersByLevel(UserLevel.Users);

Group allUsers = Group.GetUsersByLevel(UserLevel.All);
Avatar billede christian Nybegynder
27. januar 2005 - 13:47 #56
Tror mere det er:
Group admin = Group.GetByName("Admin");
Users users = admin.Users;
Avatar billede burningice Nybegynder
27. januar 2005 - 13:50 #57
christian>> men som jeg har forstået det, som ligger der stadigvæk ikke noget rettighedslag i det

Ja, du har en gruppe der hedder admin, og du kan få fat i alle brugerne i den gruppe. Men hvordan vil du kunne se hvilken rettighed en enkelt bruger har.
Avatar billede arne_v Ekspert
27. januar 2005 - 13:55 #58
Næh.

Jeg tænker slet ikke i de baner.

Det i snakker om er  er vel en Groups et eller andet som indeholder alle
instanser af Group klassen.

Man kan putte den funktionalitet i Group klassen selv, men jeg synes sjældent at det er pænt.

Et group objekt indeholder referencer til sine users, men har ikke nødvendigvis
referencer til andre grupper.
Avatar billede arne_v Ekspert
27. januar 2005 - 14:02 #59
cf>

I min model er det begge veje. Et group object har en collection af users og
et user object har en collection af groups.
Avatar billede christian Nybegynder
27. januar 2005 - 14:02 #60
Virker lidt som om alle taler forbi hinanden

Jeg ville heller ikke putte funktionalitet i Group klassen... så det skulle nok nærmere se sådan ud:
project.components.Group admin = project.bll.Group.GetByName("Admin");
project.components.Users users = admin.Users;

Via overstående kan du løber users igennem for at se hvem der er med i Admin gruppen, det var det som du spurgte om ikke?

Angående hvordan man tjekker om en bruger er med i en bestemt gruppe, ville jeg nok bruge det indbyggede i asp.net... det vil sige jeg ville lave BasePage som sørgede for at lægge den aktive brugeres grupper ind i den indbyggede asp.net Role modul.
Og den har vist nogle indbyggede IsMemberOf("Admin")
Avatar billede arne_v Ekspert
27. januar 2005 - 14:07 #61
Er Group.GetByName(string) ikke at putte groups funktionalitet i Group klassen ?
Avatar billede arne_v Ekspert
27. januar 2005 - 14:08 #62
Eller er GetByName en database metode ?
Avatar billede burningice Nybegynder
27. januar 2005 - 14:15 #63
arne_v>> det er jeg udemærket klar over

hvis du kigger på 27/01-2005 11:38:04 og 27/01-2005 11:40:06 kan du se at jeg har lavet nøjagtig den samme opbygning

Dog er der en ting som jeg tror i begge har overset... nemlig at en bruger kan have forskellige rettigheder i en enkelt gruppe

Så for mig ser scenarioet sådan her ud

Brugeren Mads er medlem af gruppen A
Line er også medlem af gruppen A

Men Mads er Admin, og Line er kun Bruger

I har fint kommet med en løsning til problemet med hvilke brugere der er i A og hvilke grupper Mads er medlem af:

Group a = Group.GetByName("A");
Users usersInA = a.Users;

Fint nok... men hvordan vi i nu finde ud af at Mads er Admin og Line er bruger ??

User mads = usersInA["mads"];
User line = usersInA["line"];

Hvad så?
Avatar billede christian Nybegynder
27. januar 2005 - 14:16 #64
Altså normalt bygger jeg mine løsnigner op således

Components (User, UserSet, Group, GroupSet etc.)
Bll (Business Logic Layer)
Dal (Data Access Layer)

Så hvis jeg skulle bruge en Component ville jeg lave et kald til Bll som ville lave det rigtige kald til Dal'en
Avatar billede christian Nybegynder
27. januar 2005 - 14:18 #65
Er vi enige om at Admin (ikke gruppe) og Bruger (ikke gruppe)
Er en property på User klassen?
Avatar billede burningice Nybegynder
27. januar 2005 - 14:23 #66
arne_v>> ang. 27/01-2005 13:55:28 så er GetByName en statisk metode på Group-klassen, for at kunne instantiere et Group-object ud fra data i databasen. I en O/R-mapper ville det måske være noget i den her retning:

Group admin = (Group)ORmapper.InstantiateNewObject(typeof(Group), "Admin"));


men det er heller ikke den konkrete implementering der er den vigtige her. Mere hvilke typer man har og hvordan deres relation til hinanden er.

Vi kan vel alle blive enige om at der skal mindst 4 klasser til

1) Group
2) GroupCollection
3) User
4) UserCollection

Group indeholder et field til en UserCollection, og User indeholder et field til en GroupCollection.

Fint nok... men hvor skal en brugers rettigheder i en given gruppe gemmes?
Avatar billede arne_v Ekspert
27. januar 2005 - 14:32 #67
Ovenstående er udelukkende en beskrivelse af forholdet mellem User og Group.

Der er ganske rigtigt ikke nogle rettigheder i det.

Men det var såmænd heller ikke meningen.

Rettigheder involverer både User/Group og X (som er det der er rettigheder til).

Jeg synes at det er svært at designe rettigheder uden at kende X.
Avatar billede arne_v Ekspert
27. januar 2005 - 14:32 #68
christian>

Nej. User klassen har kun en property Groups.
Avatar billede ibleif Nybegynder
27. januar 2005 - 14:37 #69
Jeg er selv kommet frem til følgende:
1. Users (Indeholder en collection med alle User-objekterne)
2. User (Indeholder en collection af Group)
3. Groups (Indehollder en collection med alle Group-objekterne)
4. Group (Indehollder 3 collections til at gemme sine brugere på. Hvis en bruger er admin, bliver den bruger gemt på en AdminCollection osv.)

Jeg ser ikke nogen situationer, som den opbygning ikke kan løse?

// Ibleif
Avatar billede arne_v Ekspert
27. januar 2005 - 14:38 #70
Jeg ville også kun have en collection i Group.
Avatar billede christian Nybegynder
27. januar 2005 - 14:39 #71
Okay, så en User kan have følgende rettigheder på en Gruppe "Create", "Edit", "View", "Delete"

Vil det så ikke sige at alle bruger er medlem af alle grupper? men at det ikke er sikkert at man har nogle rettigheder på alle grupperne?

Hvis vi skal komme med mere input, tror vi har brug for et eksempel på hvordan det kunne være at rettigheder var sat på Søren
Avatar billede burningice Nybegynder
27. januar 2005 - 14:40 #72
arne_v>> hvor ser du at rettighederne involvere X ?

Det er ikke det ibleif skriver i sit problem. Jeg citerer igen

"men ikke nok med det, så har hver User også forskellige rettigheder i de forskellige groups."

Altså har vi et scenarie hvor at brugeren Mads er Admin i gruppen A, men kun moderator i gruppen B.

Vi har altså ikke brug for andet end en User og en Group for at bestemme rettigheden.
Avatar billede arne_v Ekspert
27. januar 2005 - 14:48 #73
Jeg har muligvis misforstået noget.

Jeg forestiller mig:

User : ibleif, christian, cyberfessor, arne

Group : Admin, User

objekter : X1 X2 X3

rettigheder: User-X1:view Admin-X1:update cyberfessor-X1:update

Ligesom man kender det fra Windows, Access etc..

Du betragter group som objekt og har ingen "rettigheds gruppe".

Hvilket giver et noget andet resultat.
Avatar billede ibleif Nybegynder
27. januar 2005 - 15:09 #74
Ok, måske jeg har fucket op i forklaringen også? Måske rettigheder ikke skal forståes som sådan, men mere en status på den enkelte User i hver group.

F.eks. at en user kan være Admin, Moderator eller User. Hvad de enkelte status´er så giver rettigheder til, det har jeg slet ikke haft inde i mine overvejelser endnu, men bare jeg havde muligheden for at se forskel på dem, sådan at jeg ved nogle funktioner kunne kalde en metode som f.eks.

dim g as new Group("Eksperten-Spørgsmål-584519")
dim u1 as new User("arne_v")
g.AddAdmin(u1)

if g.IsAdmin(u1) then
  'Do something
End if

// Ibleif
Avatar billede burningice Nybegynder
27. januar 2005 - 15:50 #75
:) jeg har nok taget hans forklaring lidt for bogstaveligt... :) ja, jeg så kun group som en grupperinger af nogle personer... f.eks. afdelinger i et firma. Og inde i denne gruppe skal rettighederne deles op.

Men det er da rigtigt, at hvis systemet skal være ligesom Windows's ACL så vil følgende kunne bruges, som også er den model arne_v har foreslået

Følgende fire klasser:

1) Group
2) GroupCollection
3) User
4) UserCollection

Group indeholder et field til en UserCollection, og User indeholder et field til en GroupCollection.
Avatar billede burningice Nybegynder
27. januar 2005 - 15:57 #76
dog vil jeg passe på med at hardcode grupperne i koden... så til overstående vil jeg istedet gøre sådan her:

User u = User.GetByName("arne_v");

if (!u.Groups["Admin"] == null) {
  // Do something
} else {
    throw new Exception("User not allowed to edit this page");
}

Men det bliver vel et spørgsmål om præferencer
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