[ Alisa @ 05.07.2004. 14:12 ] @
Imam projekta, od kojih su 3 dll, a 4. je exe. Imam reference dll-ova u ovom exe, ali ne mogu imati reference 4. u ovim dll-ovima. Ima li nesto u C# ekvivalentno
#pragma once u C++.

Unaprijed zahvalna
[ mmix @ 06.07.2004. 11:57 ] @
Citat:
Alisa: Imam projekta, od kojih su 3 dll, a 4. je exe. Imam reference dll-ova u ovom exe, ali ne mogu imati reference 4. u ovim dll-ovima. Ima li nesto u C# ekvivalentno
#pragma once u C++.


Poruka ti je malo kriptična pa nije lako skontati šta hoćeš da postigneš. Pretpostavljam da je jedna od sledeće dve opcije:


1. Hoćeš da u DLL ubaciš referencu na EXE projekat?
Ovo ne može. Drugi EXE fajl uvek predstavlja "Application Boundary", pa se njegovi tipovi ne mogu instancirati implicitno, dodavanjem EXE fajla u references. Umesto toga, koristi se AppDomain klasa da se instanciraju tipovi iz drugog EXE fajla. Pošto ovo usporava celu priču, bolje ti je da tipove iz EXE fajla koje koristiš u DLLu prebaciš u peti DLL

2. Hoćeš da praviš kružne reference?
Tj. da DLL br. 1 referencira DLL br. 2 i da DLL br. 2 referencira DLL br. 1?
Ni ovo ne može iz više razloga. Ne bi se onda znao build order niti bi runtime znao kojim redosledom da učitava assembly-e. Ovo se u tvom slučaju rešava isto kao i pod varijantom 1. Svi tipovi koji "prave" problem iz oba DLL-a prebaciš u novi, peti, DLL i onda taj DLL referenciraš iz pomenuta dva
[ havramm @ 06.07.2004. 14:41 ] @
Tacno tako. Po meni je to vec malo pitanje dizajna. Ako bi ovo preslikali u UML ispalo bi da paket (Assembly u UML-u) A zavisi od paketa B i paket B zavisi od paketa A. A to na neki nacin lici na deadlock, zar ne?
[ shima @ 06.07.2004. 21:29 ] @
Evo šta možda možeš da uradiš:

Prvo kompajliraš exe fajl bez reference na dll (reference u sors kodu pretvori u komentare).

csc Class1.cs

Zatim kompajliraš dll sa referencom na ovaj prvi iskompajlirani exe.

csc /t:library Class2.cs /r:Class1.exe

Na kraju u prvi exe (i u sors kod) dodaš reference na kompajlirani dll i to je to.

csc Class1.cs /r:Class2.dll

Evo i sors koda (Class1.exe i Class2.dll)

Class1.cs:

public class Class1
{
Class2 class2Objct; //ovo je pod komentarom pri prvom kompajliranju
public static void Main()
{
Class1 class1Objct = new Class1();
class1Objct.CreateClass2Objct();
class1Objct.ExecuteClass2ObjctMethod();
}
void CreateClass2Objct()
{
class2Objct = new Class2 (this); //ovo je pod komentarom pri prvom kompajliranju

}
void ExecuteClass2ObjctMethod()
{
class2Objct.Class2Print(); //ovo je pod komentarom pri prvom kompajliranju

}
public void Class1Print()
{
System.Console.WriteLine("Class1 Print");
}
}

Class2.cs:

public class Class2
{
Class1 class1ObjctRef;
public Class2(Class1 class1ObjctRefInput)
{
class1ObjctRef = class1ObjctRefInput;
}
public void Class2Print()
{
class1ObjctRef.Class1Print();
}
}

_______

Vidim da je neko ovde pomminjao UML pa me zanima da li je ovakvo programiranje u redu sa projektantske (tj. teorijske) strane?

PS: Malko haka i sve šljaka...
[ dejaniv @ 14.07.2004. 09:55 ] @
Bravo za hak!

A sto se tice UMLa, to je agregacija navigabilna u obe strane.
Ja ovo nikada ne bih ovako radio, ali ako nema izbora...
Ondosno, ako mozes, promeni dizajn. Ne u smislu navigacije nego u smislu gde si sta stavio u "solution".
[ shima @ 14.07.2004. 13:59 ] @
> Bravo za hak! :)

Naravno da sam to video od profesionalaca sa zapada. Preciznije analizirajuci kod njihovih (GPL
Java) appleta. Zna se kao se dolazi do takvih stvari... :)

> Ja ovo nikada ne bih ovako radio, ali ako nema izbora...

Ovo je radjeno pri prevodjenju proceduralnog tj. strukturnog programa (npr. u C-u) u objektno
orjentisan (npr. Java applet). Zbog potrebe za visokim performansama objektni (Java) kod zadrzava
svoju strukturnu (neobjektnu) formu tj. sve se trpa u jednu klasu. Zatim se pri dodavanju novih
funkcionalnosti koje zbog dizajna (tj. uslova) projekta zahtevaju svoju posebnu klasu (npr za ovaj
aplet (tj. Class1 klasu) trazi se da se mogu od strane krajneg korisnika dodati drugi apleti tj.
klase koji koriste metode ove prve) komunikacija medju objektima se realizuje na ovakav dvosmeran
nacin.

> A sto se tice UMLa, to je agregacija navigabilna u obe strane.

Za nas koji neznamo mnogo C# i UML bilo bi veoma korisno videti source kod i dijagrame za
"agregaciju navigabilnu u obe strane" (AKO se to radi drugacije od navedenog primera). Znaci to je
legalno resenje u smislu OO projektovanja i dizajna?- tj. nije nekakav "hak"?
[ havramm @ 14.07.2004. 20:15 ] @
Citat:
dejaniv:
A sto se tice UMLa, to je agregacija navigabilna u obe strane.
Ne bih se bas slozio. Agregacija je strukturna veze (asocijacija sa adornment-om ), dok se ovde ipak radi o zavisnosti, bar iz mog ugla...
[ mmix @ 14.07.2004. 22:06 ] @
Ajoj, ubiste sa ovim prevodima UML terminologije

U UMLu možeš svašta "nacrtati", to i dalje ne znači da je to "legalno rešenje". Kad bih u svom timu prezentovao ovako nešto verovatno bi postao predmet opšte sprdnje. Zamislite nekog projektanta koji vam predlože cirkularne reference?
Sve je u redu kad za jedan red funkcionalnog koda pravite 20 linija haka, a šta ćemo sa iole kompleksnijim projektima? Ko će da džedži noću i ručno radi build (tj build1,komentiranje,build2,skidanje komentara,build3)
Uvek ima izbora, i ne postoji varijanta u kojoj si prinuđen na cirkularne reference; framework-ovi i 3rd party komponente ih nikad ne unose u priču, a za "svoj" kod si sam odgovoran, dakle imaš izbor. Ako postoji potreba za callback-ovim i ostalim povratnim šemama u .net-u, postoje delegati, gde delegati ne pomažu priča se pomera na izvlačenje sporne funkcionalnosti u zajednički modul. Cela ta priča sa hi-performace neobjektno-objektnim java apletima ne pije vodu, to je samo signal da ta aplikacija treba da se vrati na design desk, ako je uopšte nekad i boravila tamo.
[ havramm @ 15.07.2004. 00:32 ] @
Citat:
mmix: Ajoj, ubiste sa ovim prevodima UML terminologije ;)

U UMLu možeš svašta "nacrtati", to i dalje ne znači da je to "legalno rešenje".

Prosvetli nas i razresi nase dileme!
[ dejaniv @ 15.07.2004. 10:56 ] @
Citat:
shima: Za nas koji neznamo mnogo C# i UML bilo bi veoma korisno videti source kod i dijagrame za
"agregaciju navigabilnu u obe strane" (AKO se to radi drugacije od navedenog primera). Znaci to je
legalno resenje u smislu OO projektovanja i dizajna?- tj. nije nekakav "hak"?


Ovako izgleda dijagram (probao sam sa slikom pa sam provalio da ovo samo prenosi URL a ne i sliku... Ovo je finalna verzija, ne mogu da ga nateram da ovo priakze bolje.... Neko od admina bi mogao da se zabavi ovom temom...):

Code:

+---------------------+
|       Class1        |
+---------------------+
           /\   -container
           \/
           |
           |    -containee
+---------------------------+
|          Class2           |
+---------------------------+
|Class2(theConatiner:Class1)|
+---------------------------+


A ovako generisani kod:

Code:


    class Class1 
    {
        private Class2 containee;
        public Class1() { containee = new Class2(this); }
        // i tako dalje...
    };

    class Class2 
    {
        private Class1 container;
        public Class2(Class1 theContainer) { container = theContainer; }


    };


Ovo definitivno nije hak i realno se koristi. Hak je bio samo muvanje sa referencama na asemblije. Ponekad postoji potreba da objekat zna ko mu je tata da bi mogao da mu se obrati. U ovoj agregaciji sadrzan je samo jedan Class2, ali moze da ih bude vise, pri cemu se tada kao "sadrzalac" koristi neki objekat klase tipa vektor. Tada je zgodno sto svaki sadrzani sin moze da pita tatu za neku informaciju koju on zna (tipa, moze da trazi odobrenje/konkeciju da pristupi bazi).

Cool?

[ mmix @ 15.07.2004. 12:20 ] @
Citat:
havramm: Prosvetli nas i razresi nase dileme!


Nema potrebe, dejaniv je dao rešenje, i to legalno, ali to rešenje nema veze sa prvobitnom pričom u ovom topicu, pošto su obe klase u istom modulu, što je i bilo prvobitno predloženo rešenje (izdvojiti ciklični kod u peti dll). Probajte sad ovo rešenje da podelite u dva DLL-a i tad nastaje problem. Onda mora hak, a kad takav pristup primenite na 10-15 modula, počinje noćna mora, a UML ti savršeno dozvoljava da priču podeliš na X modula.
Dalje, i po ovom legalnom rešenju, kad projekat radi više ljudi, tipa desetak, uvek bude neko pametan, pa brzo počinje cimka "daj šta si to menjao, puca mi build", itd, itd, pa se na kraju taskovi u timu dele po modulima, što nije uvek najpametniji pristup. Delegati (koji funkcionišu kao Eventi u COMu) su elegantno rešenje iako nisu tako brzi kao direktno pozivanje metode ali opet imaju zgodnu osobinu da više dece može da se nakači na jedan sink, tako da u sistemu gde jedan container sadrži n dece, bivaju pozivana samo ona deca kojoj to treba. Ljudi generalno izbegavaju delegate, valjda loš trip iz doba COMa kad je za jedan event trebalo "prekucati" dosta koda, sad je sve dovoljno elegantno da se može lahko koristiti.