[C#] Factory method met classes in verschillende namespaces

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

  • bdgroot
  • Registratie: Augustus 2002
  • Laatst online: 27-11-2024
Ik heb het volgende probleem en ik zoek naar een mooie oplossing.

Ik heb een namespace documentProject. In deze namespace zitten algemene Business-objecten. Een daarvan is Document.
Ik heb ook een namespace documentProject.afdeling1 In deze namespace zitten Business-objecten die alleen voor afdeling1 relevant zijn. Daarin heb ik een subclass van Document, namelijk afdeling1Document. Hetzelfde geldt voor afdeling2, alleen heb ik daar dan afdeling2Document in documentProject.afdeling2.

Nu de situatie.

Ik klik in de UI van afdeling1 op een knopje voor een nieuw document. daarbij wordt er een aspx genaamd document.asp geopend (in de namespace documentProject.UI). Daarin moet een nieuw object gemaakt worden van de class documentProject.afdeling1 (omdat ik dus in afdeling1 zit). Ik KAN in documentProject natuurlijk "using documentProject.afdeling1;" toevoegen, maar dat wil ik niet, want anders die hele structuur niet zinvol meer is. Zijn hier nog meer oplossingen voor te bedenken?

Als je meer wilt weten, dan hoor ik het wel... Ik kan best nog iets over het hoofd zien.

Laat een computer nooit merken dat je gehaast bent.


  • pjvandesande
  • Registratie: Maart 2004
  • Laatst online: 16-04 11:36

pjvandesande

GC.Collect(head);

Als je iets nodig hebt uit een anderen namespace zou je die gewoon moeten usen of je dat nou met using doet of de gehele namespace en classname specificeren bij het instantieren maakt niet uit.

Je UI namespace hoort toch ook gebruik te maken van je afdeling1 namespace, dit komt bij mij niet vreemd over? Maar ik moet zeggen dat ik je probleem ook niet echt begrijp.

  • joopst
  • Registratie: Maart 2005
  • Laatst online: 01-10-2024
je factory geeft een instantie van de document-class terug. De UI weet dus niet welke het is. Omdat alle bewerkingen en properties die je nodig hebt zijn gedefinieerd op je document-class (waar je afd1 en afd2 classen van erven).
De interne implementatie kan anders zijn voor afd1 en 2, maar daar hoeft de UI niks van af te weten en daarom kan die dus gewoon met de documentclass werken.

als het goed is, heb je dat probleem van die namespaces dus niet :)

  • pjvandesande
  • Registratie: Maart 2004
  • Laatst online: 16-04 11:36

pjvandesande

GC.Collect(head);

Je GUI hoeft alleen maar te weten dat het een document is. Dus je hoeft binnen je GUI niet DocumentProject.Afedling1 te usen.

Maar dat is geen probleem van namespaces.

Je geeft je abstract base class Document een static Create method die adhv config settings een goede implementatie teruggeeft.

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public abstract class Document
{
     public static Document Create()
     {
          switch(Settings["DocType"])
          {
               case "Afdeling1"
                    return new DocumentProject.Afdeling1.Afdeling1Document();
               case "Afdeling2"
                    return new DocumentProject.Afdeling1.Afdeling2Document();
               default:
                    throw new SettingException("Unknown doctype.");
           }
}

  • bigbeng
  • Registratie: Augustus 2000
  • Laatst online: 26-11-2021
Hiermee leg je wel een sterke afhankelijkheid en benodigde kennis van het base-object ten opzichte van implementaties. Het is imho beter om een factory te maken die de documenten aanmaakt.

  • bdgroot
  • Registratie: Augustus 2002
  • Laatst online: 27-11-2024
@questa: het gaat om het plaatsen van de verantwoordelijkheden op de juiste plaats. In documentProject wil je niet dat dingen van afdeling1 gaat afhandelen, want daarvoor is nu juist die documentProject.afdeling1 gemaakt. Bekijk de hierarchie: documentProject staat boven afdeling1, afdeling2 en UI. In UI kun je best afdeling1 en afdeling2 usen, dat is niet meer dan logisch. Maar UI ga je juist niet in documentProject usen lijkt me (net als afdeling1 en afdeling2 dus).

@joopst: Jij zegt dus dat die subklassen niet nodig zijn... en dat je dat in 1 klasse stopt. Maar dat is het nou net: dat wil ik eigenlijk niet. Nu zit In afdeling1 namelijk een property die specifiek voor afdeling 1 geldt en in afdeling2 één specifiek voor afdeling2. Bij jouw oplossing krijg je een class waarin die properties allebei zitten en in elk object een van die 2 leeg is. Op dataniveau is dat iets dat wel kan, maar in je business logic niet vind ik. Verder is het zo dat dit nog maar gaat om 2 properties die verschillen, maar ik heb dezelfde situatie ook voor veel grotere classes in een stuk of 4 andere namespaces en dat wil ik graag opgelost hebben.

@bigbeng: dat vind ik dus ook. Maar dan is dus het probleem van de namespaces er weer: ik kan in documentProject niet bij documentProject.afdeling1.afdeling1Document, want daar weet ik niet van het bestaan ervan af.. tenzij ik afdeling1 ga usen (en dat wil ik dus weer niet)...

[ Voor 12% gewijzigd door bdgroot op 09-12-2005 14:03 ]

Laat een computer nooit merken dat je gehaast bent.


  • pjvandesande
  • Registratie: Maart 2004
  • Laatst online: 16-04 11:36

pjvandesande

GC.Collect(head);

bdgroot schreef op vrijdag 09 december 2005 @ 13:56:
@questa: het gaat om het plaatsen van de verantwoordelijkheden op de juiste plaats. In documentProject wil je niet dat dingen van afdeling1 gaat afhandelen, want daarvoor is nu juist die documentProject.afdeling1 gemaakt. Bekijk de hierarchie: documentProject staat boven afdeling1, afdeling2 en UI. In UI kun je best afdeling1 en afdeling2 usen, dat is niet meer dan logisch. Maar UI ga je juist niet in documentProject usen lijkt me (net als afdeling1 en afdeling2 dus).
Ja, maar dat kan toch met een Factory of een Create method voor Documenten?
@joopst: Jij zegt dus dat die subklassen niet nodig zijn... en dat je dat in 1 klasse stopt. Maar dat is het nou net: dat wil ik eigenlijk niet. Nu zit In afdeling1 namelijk een property die specifiek voor afdeling 1 geldt en in afdeling2 één specifiek voor afdeling2. Bij jouw oplossing krijg je een class waarin die properties allebei zitten en in elk object een van die 2 leeg is. Op dataniveau is dat iets dat wel kan, maar in je business logic niet vind ik. Verder is het zo dat dit nog maar gaat om 2 properties die verschillen, maar ik heb dezelfde situatie ook voor veel grotere classes in een stuk of 4 andere namespaces en dat wil ik graag opgelost hebben.
Nee, dat maak ik niet op uit zijn post. Het zijn verschillende implementaties, die horen gescheiden.

  • joopst
  • Registratie: Maart 2005
  • Laatst online: 01-10-2024
@joopst: Jij zegt dus dat die subklassen niet nodig zijn... en dat je dat in 1 klasse stopt.
nee, dat zeg ik niet :)

ik zeg dat je 3 klassen maakt, 1 basis en 2 (specifieke) die ervan erven.
de factory maakt instanties van specifieke klassen.

OO maakt het mogelijk dat je dan in de UI niet hoeft te weten of je met specifieke1 of specifieke2 werkt. Omdat je dat niet hoeft te weten, hoef je ook die namespaces niet te importeren.

  • bdgroot
  • Registratie: Augustus 2002
  • Laatst online: 27-11-2024
Hey.. volgens mij gaat er een lichtje branden nu. Ik ga eens kijken of dat is wat ik echt zoek :)

Laat een computer nooit merken dat je gehaast bent.


  • whoami
  • Registratie: December 2000
  • Laatst online: 21-04 17:18
bdgroot schreef op vrijdag 09 december 2005 @ 13:29:

Ik klik in de UI van afdeling1 op een knopje voor een nieuw document. daarbij wordt er een aspx genaamd document.asp geopend (in de namespace documentProject.UI). Daarin moet een nieuw object gemaakt worden van de class documentProject.afdeling1 (omdat ik dus in afdeling1 zit). Ik KAN in documentProject natuurlijk "using documentProject.afdeling1;" toevoegen, maar dat wil ik niet, want anders die hele structuur niet zinvol meer is. Zijn hier nog meer oplossingen voor te bedenken?

Als je meer wilt weten, dan hoor ik het wel... Ik kan best nog iets over het hoofd zien.
Ik zie eerlijk gezegd het probleem niet.
use gewoon de juiste namespaces in die andere namespace, zodanig dat je een factory kunt maken zoals je wil.

Een structuur leg je ook niet vast dmv namespaces. Een namespace zorgt er gewoon voor dat je verschillende classes kunt hebben met dezelfde naam, maar dan moeten ze wel in een andere namespace zitten.
Structuur leg je vast mbhv assemblies.

Niet gaan over-engineren he. Wat is het probleem als project iets 'afweet' van project.afdeling1 ?
Zoals ik het nu begrijp, zitten al deze classes in eenzelfde DLL ?

https://fgheysels.github.io/


  • bdgroot
  • Registratie: Augustus 2002
  • Laatst online: 27-11-2024
Ow.. sh** ik heb wat door elkaar gehaald :? Ik bedoel dus een andere assembly.. tja.. ik ben nog niet zo heel lang into de taal en het de structuur die ik hier gebruik.

De classes zitten alle 3 in aparte dll's.

[ Voor 12% gewijzigd door bdgroot op 09-12-2005 14:25 ]

Laat een computer nooit merken dat je gehaast bent.


  • whoami
  • Registratie: December 2000
  • Laatst online: 21-04 17:18
Dan heb je imho 2 opties:
- of je maakt een nieuwe assembly waarin je je factory steekt, en die assembly heeft referenties naar de betreffende assemblies
- of je gaat de IoC toer op.

https://fgheysels.github.io/


  • bdgroot
  • Registratie: Augustus 2002
  • Laatst online: 27-11-2024
ehhh.. IoC?

Laat een computer nooit merken dat je gehaast bent.


  • Plekuz
  • Registratie: September 2002
  • Laatst online: 02-01 15:26

Plekuz

available in strong mint

Waarom voor ieder object een andere namespace? Dat is niet nodig. Je kunt twee "DLLs" maken, waarbij iedere DLL classes heeft in dezelfde namespace. Dan kennen ze automatisch elkaar en kun je in Document gewoon een Document.Afdeling1 aanmaken.

Overigens zitten ze echt in aparte DLLs of slechts in aparte CS bestanden binnen 1 project? Ik kreeg namelijk het gevoel dat je niet echt dlls bedoelde namelijk ...

[ Voor 28% gewijzigd door Plekuz op 09-12-2005 14:35 ]

"There he goes. One of God's own prototypes. Some kind of high powered mutant never even considered for mass production. Too weird to live, and too rare to die."


  • whoami
  • Registratie: December 2000
  • Laatst online: 21-04 17:18
Inversion Of Control / Dependency Injection / Spring.NET

Eigenlijk komt het er op neer dat je at runtime een assembly laad, en dan de een object instantieert van een type uit die dll.

Je kan ook mbhv reflection ed aan de slag om zelf zo iets te maken.

https://fgheysels.github.io/


  • bdgroot
  • Registratie: Augustus 2002
  • Laatst online: 27-11-2024
Nog maar 1 keer duidelijk dan:
Een dll documentProject met een namespace documentProject die o.a. een class Document (dus een .cs) bevat
Een dll documentProject.afdeling1 met een namespace documentProject.afdeling1 die o.a. een class Afdeling1Document (dus een .cs) bevat
Een dll documentProject.afdeling2 met een namespace documentProject.afdeling2 die o.a. een class Afdeling2Document (dus een .cs) bevat

Laat een computer nooit merken dat je gehaast bent.


  • bigbeng
  • Registratie: Augustus 2000
  • Laatst online: 26-11-2021
Wat is de dieperliggende gedachte om documentProject en zijn werkelijke implementaties te scheiden van elkaar in de zin van assemblies? Verwacht je dat de implementaties los van elkaar gebruikt gaan worden? Moet het voor een derde applicatie mogelijk zijn om de Business Logic uit documentProject te omzeilen en direct met de implementaties (bv documentProject.afdeling1) aan de slag te gaan? Zo ja, steady as you were, zo nee, samenvoegen die assemblies.

  • bdgroot
  • Registratie: Augustus 2002
  • Laatst online: 27-11-2024
Yepz.. dat is de bedoeling inderdaad :)

Laat een computer nooit merken dat je gehaast bent.


  • Plekuz
  • Registratie: September 2002
  • Laatst online: 02-01 15:26

Plekuz

available in strong mint

Even terug naar het begin:

Je hebt een class genaamd Document, daarvan leid je 2 classes af Document.Afdeling1 en Document.Afdeling2. Kortom: deze twee laatste classes bevatten ook alle functionaliteit van de class Document.

Waarom is er dan geen Document.Afdeling1.UI waarin een nieuw object van Document.Afdeling1 aangemaakt wordt? Nu probeer je 'm op de parent aan te maken en dat is vreemd. Je zou met een interface op de parent en een implementatie daarvan in de afgeleide classes ook nog een eind kunnen komen.

[ Voor 54% gewijzigd door Plekuz op 09-12-2005 15:25 ]

"There he goes. One of God's own prototypes. Some kind of high powered mutant never even considered for mass production. Too weird to live, and too rare to die."


  • bdgroot
  • Registratie: Augustus 2002
  • Laatst online: 27-11-2024
neej.. assemblies Document.afdeling1 en 2, met classes afdeling1Document en afdeling2Document, maar dat doet niet veel af aan je verdere oplossing.

Het systeem zit nog iets complexer in elkaar als ik verder verteld heb, maar dat heeft geen invloed op de situatie die ik schets. Binnen documentProject is er een assembly UI die een aantal namespaces (ja namespaces) heeft (o.a. afdeling1, afdeling2). Daar wordt alles van de UI geregeld. document.aspx komt daarin voor in de namespace documentProject.

Laat een computer nooit merken dat je gehaast bent.


  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

Inversion of Control for noobies:

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
public interface IDocument
{
 // functies
   string Afdeling { get; }
}

public class DocumentType1 : IDocument
{
    DocumentType1()
    {}
    // implementatie
    string Afdeling { get { return "afdeling1" } }
}

public class DocumentType2 : IDocument
{
  DocumentType2()
  {}
  //implementatie
  string Afdeling { get { return "afdeling2" } }
}

public class DocumentFactory
{
   private ArrayList documentTypes = new ArrayList();
   public DocumentFactory()
   {
     foreach (string file in System.IO.Directory.GetFiles(System.IO.Directory.GetCurrentDirectory(),"*.dll"))
    {
        try
        {
            Assembly ass = Assembly.LoadFile(file);
            foreach (Type type in ass.GetTypes())
            {
                if (type.IsClass && !type.IsAbstract)
                {
                    if (type.GetInterface(typeof(IDocument).ToString(),true) != null)
                        documentTypes.Add(type.GetConstructor(Type.EmptyTypes).Invoke(null));
                }
            }
        }
        catch (BadImageFormatException bife)
        {}
        catch (ReflectionTypeLoadException rtle)
        {}
    }
   }

   public IDocument GetDocument(string afdeling)
   {
      foreach (IDocument doc in documentTypes)
      {
          if (doc.Afdeling == afdeling)
             return doc;
      }
   }
}


Dit is slechts 1 vorm hiervan.
dit kan bvb ook:
C#:
1
2
3
4
5
6
7
8
9
public interface IDocument
{
   IDocument Clone();
}

// ... in factory
         if (doc.Afdeling == afdeling)
             return doc.Clone()
// ... in factory


enz enz...
De implementatie die je kiest is afhankelijk van jouw noden en jouw situatie.
als je bovendien Google't op Inversion of Control dan is de eerste site als ik me niet vergis een hele goeie...

ASSUME makes an ASS out of U and ME

Pagina: 1