Laden...
Avatar #avatar-2316.jpg
JuyJuka myCSharp.de - Experte
Fachinformatiker: Anwendungsentwicklung Deutschland Dabei seit 30.11.2005 2.187 Beiträge
Benutzerbeschreibung
Ich liebe OO und vor allem OOD. Mit Klassen, Interfaces, Assoziaitonen, Vererbung, Kapselung, Patterns und und und verbring ich meine Arbeits- und meine Freizeit. *stahl*

Forenbeiträge von JuyJuka Ingesamt 2.187 Beiträge

09.12.2009 - 20:50 Uhr

Hallo sth_Weird,

Das ganze für jede Datenquelle als eigene Klasse bzw. App-Config eintrag zu machen ist richtig.
Die UI darf auch nicht direkt diese Klasse(n) kennen, jedoch kannst du die Klassen zur Laufzeit an die UI übergeben. Das PropertyGrid kann jeder Klasse darstellen. Alternativ könntest du auch in der UI eine Schnittstelle definieren, über die du "Konfiguratins-Steuerelemente" lädst, dann noch eine Assembly das jene UI-Schnittstelle und die konkrete Konfigurations-Klasse kennt und so eine UI für die konkrete Konfigurationsklasse enthalten kann. Wird die implementation der UI-Schnittstelle jetzt in die "normal" UI-Schicht injiziert/geladen/etc. , hat man ein sauberes 3-Schichten-Model.

Gruß
Juy Juka

08.12.2009 - 13:42 Uhr

Hallo idzik,

Du bist ein bischen zu festgelegt. Die BL muss weder als Singelton noch als Konstruktorparameter existieren. Das kommt immer auf den Anwendungsfall an und kann im zweifelsfall unterschiedlich implementiert sein.
Was aber richtig ist, dass man ein Interface hat (z.B. IDateTimeProvider) und nur mit diesem Interface im restlichen Code arbeitet. Woher die konkrete Instanz kommt, ist dann wieder ein losgelöstes Thema (Einfach Microkernel, Dependenci Injection oder Inversion of Control in der Forensuche verwenden).

Gruß
Juy Juka

08.12.2009 - 12:30 Uhr

Hallo st_Weird,

Da wahr JAck30lena schneller als ich und hat (wie zu erwarten) auch recht. Wenn eine Schicht ausgetauscht werden kann, ohne in der/den anderen Schichten Code zu ändern ist es richtig implementiert.

Wenn ich Tier lese muss ich unwillkührlich sofort and Verteilte Anwendungen denken, aber du meinst hier Schichten (unabhängig von der Verteilung). Richtig?

Gruß
Juy Juka

07.12.2009 - 20:12 Uhr

Hallo Doret,

Das kannst du am besten mit dem configSource-Attribut.
Man kann damit die configSection des DLL-Projekts aus der dortigen app.config in eine seperate Datei legen, die selbe Datei wird per Link und "Immer kopieren" in die ausgabe des *.exe-Projekts kopiert und schließlich kann man dann in der app.config des *.exe-Projekts mit dem gleichen configSource-Attribut kann man jetzt die Datei einbinden.

App.config der DLL


<configuration>
  <configSections>
    <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
      <section name="Test.Dll.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
    </sectionGroup>
  </configSections>
  <applicationSettings>
    <Test.Dll.Properties.Settings configSource="Test.DLL.config" />
  </applicationSettings>
</configuration>

Extra-Datei (Test.DLL.config)

<?xml version="1.0" standalone="yes"?>
<Test.Dll.Properties.Settings>
  <setting name="Waehrung" serializeAs="String">
    <value>€</value>
  </setting>
</Test.Dll.Properties.Settings>

App.config der EXE


<configuration>
  <configSections>
    <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
      <section name="Test.Dll.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
      <section name="Test.Exe.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
    </sectionGroup>
  </configSections>
  <applicationSettings>
    <Test.Dll.Properties.Settings configSource="Test.DLL.config" />
    <Test.Exe.Properties.Settings>
      ...
    </Test.Exe.Properties.Settings>
  </applicationSettings>
</configuration>

Gruß
Juy Juka

30.11.2009 - 11:09 Uhr

Hallo Florian Reischl,

Deine Argumente kann ich SEHR gut nachvollziehen. Das ist oft so, dass ein Tool verflucht wird, weil der Verwendet keine Ahnung hat, was es eigentlich tun soll.

O/R Mapper (wie alle anderen Hilfsmittel) haben einen allgemeinen Vorteil und einen allgemeinen Nachteil.
Vorteil: Das Wissen muss nicht mehr im Kopf des Anwenders sein.
Nachteil: Das Wissen muss nicht mehr im Kopf des Anwenders sein.
Es ist schön, dass jeder es Benutzen kann, nur schade, dass es so auch jeder falsch Benutzen kann.

Naja, jetzt hab ich tatsächlich einen schönen langen Post, der im endefeckt nichts neues sagt. 😄
Aber wenigstens zu deiner Aufmunterung: Du bist nicht der Erste der das so sieht und vermutlich auch nicht der Letzte und auch nicht alleine mit deiner Meinung.

Gruß
Juy Juka

30.11.2009 - 10:59 Uhr

Hallo snupi,

Man kann eine Datei einfach per Resources-Designer einbinden, der kleine Pfeil neben "Resource hinzufügen" macht das.

Die Datei wird dann als Text-Datei gespeicher. Diese kann man über Properties.Resources laden, den Text in einen StringReader (=Stream) umwandeln und damit das Xml-Dokumen laden.

Gruß
Juy Juka

21.11.2009 - 03:31 Uhr

Hallo Berian,

IDataErrorInfo bringt nur etwas, wenn du den Fehler in deiner Klasse feststellst (und da könnte man auch eine Exception werfen).

Um den Fehler in der UI zu bekommen (egal ob er von dir oder vom .Net-Framework erzeugt wird) verwende einfach den ErrorProvider. Diese Komponente gibt's in der ToolBox und wenn du diesen auf die Maske ziehst und mit deiner BindingSource verbindest werden alle Fehler auf der Maske angezeigt.

Gruß
Juy Juka

18.11.2009 - 09:34 Uhr

Hallo,

spike24 hat schon recht, man kann das von Außen lösen oder in der Klassen in dem man IEnumerable implementiert. IEnumerable wäre eine Implementation des Visitor-Patterns (das ist erweiterbar und so). Ohne an der Klase erwas zu ändern ginge es wie folgt:


HTML tag_html = new HTML();
foreach(List<string> liste in new List<string>{
  tag_html.List1,
  tag_html.List2,
  ... // hat halt ein Problem wenn Listen dazukommen (z.B. in Kind-Klassen), aber dafür gibts ja IEnumerable
})
{
  foreach (string tag in liste.OrderBy(pl => pl.Substring(0, 1)))
  {
    //...
  }
} 

Gruß
Juy Juka

18.11.2009 - 09:11 Uhr

Hallo Cheeesi,

Such doch mal nach einer Klasse Programm bzw. einer Methode namens Main.
Darin gibt's ein Array mit den Parametern (args) für dein Programm.
Aber so was findet sich auch ganz easin in :rtfm: oder mit ner Suchmaschiene.

Gruß
Juy Juka

18.11.2009 - 08:31 Uhr

Hall ZeroQool,

Wir arbeiten per SVN und haben im Netzwerk Server für alle zur Verfügung (MSSQL, Oracle, MySql, IIS, etc.) auf denen man Entwickeln kann. Zusätzlich hat jeder noch mal lokal Server, die er auch zum Entwickeln nehmen kann (nicht alle). Aber das wichtigste ist, dass wir alles so entwickeln, dass es auf allen OS/IIS läuft (bzw. laufen sollte 😄 ).

Gruß
Juy Juka

18.11.2009 - 07:59 Uhr

Hallo Sebi,

Was für ein Container?

Test-Möglichkeit 1: Ich fülle das Property Comparer ganz klasisch mit meinem Mock-Objekt.

Test-Möglichkeit 2: Ich registriere im Microkernel einen Mock-Comparer als Implementation von IComparer<T>.

Gruß
Juy Juka

17.11.2009 - 10:32 Uhr

Hallo Rodney, Hallo Noodles,

Wenn die BindingList den Typ nicht über einen Standard-Konstruktor instanziieren kann (bei einem Interface wie Rodney es angibt geht das per Definition nicht) kann die BindingList keine neuen Objekte erzeugen.

Jedoch bietet die BindingList folgende Möglichkeiten das Objekt selbst zu erzeugen:

  1. Methode in der BindingList überschreiben
protected virtual object AddNewCore()
  1. BindinList AddingNew-Event abonieren und in den AddingNewEventArgs das Property NewObject füllen.

Gruß
Juy Juka

17.11.2009 - 10:17 Uhr

Hallo PeterBucher,

Erst mal sorry, dass ich mich so lange nicht gemeldet habe.

Um all das musst du dich nicht kümmern, bzw. ...

Das Brauche ich auch mit dem Microkernel in dieser Sittuation nicht beachten, da die Klassen das ja wieder intern regeln.

  1. Lazy Instantiation und 2. einen Singleton

Beides lässt sich auch mit einem Microkernel konfigurieren, wenn er das Unterstützt oder soger nachimplementieren, wenn er es nicht unterstützt.

Wenn es ein Vorteil sein soll, das Unwissen auch unterstützt wird, gebe ich dir Recht.
Ich gehe aber davon aus, das die Leute wissen, was sie tun.

Ich gehe davon aus das die Leute keine Ahnung haben 😉 so werden die Bibliotheken etc. einfacher benutzbar aber eigentlich geht es um die Lesbarkeit des Codes, nicht um das Unwissen.

Im Endeffekt reden wir hier über winzige Nuauncen, die sich zu 99% bei beiden Technologien umsetzbar sind. Ich hab bis jetzt kein Killer-Kriterium für oder gegen IoC oder für oder gegen Microkernel gesehen (nur kriterien dagegen keins von Beiden zu verwenden).

Gruß
Juy Juka

11.11.2009 - 09:00 Uhr

Hallo Peter Bucher,

Service Locater => Der mir bekannte original Titel des Architekturpatterns ist Microkernel, aber ich glaube beide Beschreiben das gleiche.

Wenn man die Verknüpfungen im Code hinterlegt, ist es natürlich sicherer. Guter Einwand.

Ich finde Dependency Injection unleserlicher als Microkernel. Bei Microkernel hat man immer noch einen normalen Aufruf, der auch im Code steht und von jedem Nachvollzogen werden kann (er mag nicht verstehen warum da nicht new steht, aber er sieht das ein Objekt abgerufen/erzeugt wird).
Pseudod Code:
Microkernel


private IComparer<T> _Comparer = null;
public IComparer<T> Comparer
{
  get
  {
    if(this._Comparer==null)
      this._Comparer = Microkernel.Create<IComparer<T>>();
    return this._Comparer;
  }
  set{ this._Comparer = value; }
}

Dependency Injection


public IComparer<T> Comparer{get;set;} // hier sieht man halt überhaupt nicht das irgend wo etwas erzeugt wird, normal müsste es null sein.


[Inject] // Manchmal gibt es noch Attribute oder so, da hat man wenigstens noch einen hinweis, muss jedoch selber noch wissen, was das Attribut und wann verursacht
public IComparer<T> Comparer{get;set;}

Außerdem wird bei Dependency Injection der StackTrace durcheinander gewirbelt, bei Microkernel nicht. Das zweite ist jetzt zwar nicht das killer Argument, aber ich seh halt auch keinen Vorteil bei Dependency Injection

Gruß
Juy Juka

10.11.2009 - 19:29 Uhr

Hallo @all,

Diese Diskusion haben wir hier schon bis zum erbrechen ( und kontrovers ) gehabt.

Ja 🙂 dann geb ich mal liebe ruhe. 😉

Zur Vollständigkeit:
typed oder untyped Dataset
3-Schichten-Design?? [harte vs. weiche (Daten-)Objekte / OOP vs. ActiveRecods]

Gruß
Juy Juka

10.11.2009 - 19:19 Uhr

Hallo @all,

Die fehlende Compiler-Überprüfung ist wirklich ein Nachteil.

Die Komplexität steigt durch Dependenci Injection nicht zu viel an (im Vergleich zu sauber programmierten Anwendungen die auch Interfaces verwenden), jedoch wird der Code um einiges unleserlicher, da man nicht sehen kann wo Objekte herkommen und man dem Code nicht mehr folgen kann, da der Stacktrace/Ablauf unterbrochen wird. (Ich würde mich hier für Microkernel anstadt für Dependenci Injection entscheiden, das ist aber meine Meinung).

Gruß
Juy Juka

10.11.2009 - 18:47 Uhr

Hallo gekr,

Es macht nicht wirklich einen Unterschied. Die Initalisierung hinter der Dekleration wird einfach nur in jeden Konstruktor kopiert.
So lange man also nur einen Konstruktor hat ist es egal und bei den anderen auch (so gut wie) nur Geschmackssache.

Gruß
Juy Juka

04.11.2009 - 16:45 Uhr

Hallo Cupid ,

Nicht verzagen. 😃 Es hört sich alles schwieriger an als es ist. Irgend wann macht es mal click und ab dann ist es einfach.

Hier beschreibe ich mal, wie ich es machen würde. Das ist ein möglicher Weg, ander würden eventuell andere Wege bevorzugen.

Erstmal ein kleines Szenario:
Ich habe eine Liste mit Beständen, die bestehen einfach nur aus Name und Menge. Diese Liste will ich verwalten.


// eine Klasse um einen Bestand zu bearbeiten
public interface IBestand
{
  string Name{get;set;}
  decimal Wert{get;set;}
  void Save();
}
// eine Klasse um Bestände zu laden
public interface IBestandRepository
{
  IEnumerable<IBestand> GetBestand(...); // stadt ... natürlich suchparameter
}

Das war schon der ganze Trick. In jeder Maske/Klasse/Form/WPF-Form (was auch immer) kannst du jetzt eine Instanz (ein Objekt) von IBestandRepository erzeugen oder von außen übergeben bekommen (diese sind ja unwichtig) und dir alle benötigten IBestand-Objekte daraus hohlen.

Der nächste Schritt wäre dir zu überlegen, welche Klassen (die wie IBestand sind) du für deine Anwendung brauchst. Ich empfehle hier eine Dokumentenanalyse durchzuführen. (Aber du kannst auch hier Informationen posten und dir von uns helfen lassen.)

Gruß
Juy Juka

26.10.2009 - 09:28 Uhr

Hallo Tarion,

Der Code den du da so als "unnötig" beschreibst hat schon seinen sinn. Man könnte auch mit weniger die Sache zum Laufen bringen, jedoch hat jedes der eingesetzen Elemente seinen Sinn (Wiki und Co. sollten diesen erschließen lassen).

Außerdem kann man sich für 1. und 2. viele verschiedene Implementationena aus dem INet besorgen. Man muss nur schauen, welche am Besten in die Softwar hinein passt (das heißt meißtens, welche am besten mit der Datenzugriffsschicht zusammen passt/arbeitet). ([eigenwerbung] |Aisys| O/R Mapper [/eigenwerbung]

Für 3. PAC hab ich leider keine Implemenatation gefunden aber vielleicht bekomme ich meine ja irgend wann fertig und stelle Sie online.

Gruß
Juy Juka

21.10.2009 - 13:13 Uhr

Hallo JAck30lena,

  1. Ich kann dir sagen warum der Code bei mir nicht funktionieren würde:
newDomain.AssemblyResolve += new ResolveEventHandler(newDomain_AssemblyResolve);

In dieser Zeile würde die Assembly aus der ich die neue AppDomain erzeuge in die neu AppDomain geladen werden müssen und genau das ging bei mir nicht, da die Assembly nicht im richtigen Verzeichniss liegt.

  1. Ich habe den Ansatz mit dem Probing mal weiter gesponnen:
    Ich verwende jetzt ein Verzeichnis das "über" dem Verzeichniss mit der DLL mit dem Prüfenden Code liegt und über dem Verzeichniss mit den zu prüfenden DLLs liegt. Dadurch kann ich das Verzeichniss mit den zuprüfenden und der prüfenden DLL beide als Probing angeben.

<root>
-> VerzeichnissA
-> Pruefsoftware.dll (≤die wird so zu sagen ausgeführ)
-> VerzeichnissB
-> ZuPruefende.dll

Ich lege also ApplicationBase auf <root> fest und binde VerzeichnisA und VerzeichnisB als Probing für die neue AppDomain ein.

Jetzt bin ich zwar mit den Verzeichnissen eingeschränkt aber das ist mir lieber als die Puefsoftwar.dll in das zu überprüfende Verzeichniss zu kopieren.

Also Danke für deine Hilfe Jack30lena das Probing war der Lösungsweg für mich.

Gruß
Juy Juka

21.10.2009 - 10:34 Uhr

Hallo JAck30lena,

Hab die Assembly auch schon als byt[] gelesen. Die Methode funktioniert einwandfrei, will ich dann aber einen Typ aus diesem byte[]-Assembly verwenden (per Reflection über die Domain-Grenzen hinweg) sucht er wieder nach der Datei.
So weit ich das gelesen habe sind Load(...) und das Normale Assembly-Laden zwei verschidene "Scopes" (oder so) in der AppDomain und werden nicht voneinander beeinflusst.
AssemblyResolve abzufangen hab ich auch versucht, aber um den Delegaten zu Registrieren muss er auch wieder das Assembly laden => Die Katze beißt sich in den Schwanz.

Gruß
Juy Juka

21.10.2009 - 10:15 Uhr

Hallo JAck30lena,

vielleicht solltest du für diese validierung eine eigene appdomain erzeugen?

Mach ich ja. Ich hab das Verzeichniss jedoch als ApplicationBase übergeben, ich probier das mal als Probing ... naja, Probing ist doch normal nur für Untergeordnete Verzeichnisse, oder?

Gruß
Juy Juka

21.10.2009 - 09:55 Uhr

Hallo JAck30lena,

Du hast richtig erkannt, was ich machen möchte, nur leider funktioniert das auch nicht.

Wenn ich einen Delegat in die andere Domain übergebe, dann will er in dieser Domain den dazugehörigen Typ laden, aber genau das geht ja nicht, da sich das Assembly sonst wo befindet, nur nicht im ApplicationBase-Verzeichnis.

Gruß
Juy Juka

21.10.2009 - 09:30 Uhr

Hallo Leute,

Um TypenNamen zu validieren möchte ich folgenden Code ausführen:


Type.GetType(assemblyQualifiedName,false)!=null

Da ich die TypenNamen aber nicht für die aktuelle Anwendung, sondern für eine andere Anwendung prüfe, muss ich das aus einem anderen Verzeichniss (ApplicationBase) prüfen und am besten die Assemblies auch wieder entladen.
Das geht ja alles per AppDomain, jedoch hab ich jetzt das Problem, dass ich den Code (siehe oben) nicht in die ZielDomain hinein bekommen, da meine eigene Assembly ja nicht im ApplicationBase-Verzeichnis liegt.
Ich habe jetzt alles mögliche Versucht (Load(AssemblyName), Load(byte[]), DefineDynamicAssembly()) aber bekomme den Code nicht in die Domain.

Hat jemand eine Idee wie man das lösen kann oder Suchbegriffe für mich?

Gruß
Juy Juka

21.10.2009 - 09:02 Uhr

Hallo Tarion,

Das Thema hab ich auch schon mal hier eröffnent: Architektur/Pattern(s)/Framework für UI-Abkopplung

Ich versuche im Moment folgende Kombination (ich hab aber noch keine Erfolgsmeldung):

  1. Lose Kopplung der Softwareteile durch Interfaces und Microkernel.
IModel m = Micorokernel.Create<IModel>();
  1. Zugriff auf die vershiedenen Model-Teile durch abstact Factory.
IFactory<IModel> m = Microkernel.Create<IFactory<IModel>>();
  1. Entkoplung der Präsentation durch PAC.
TopLevelAgent.Instanz.Anzeigen(Microkernel.Create<IModel>());

Gruß
Juy Juka

12.10.2009 - 13:09 Uhr

Hallo CrazyMetal,

Beschreib doch erst einmal, was du als Ergebnis der Abfrage haben möchtest und welche Einschränkungen du haben möchtest - sauber getrennt und wenn möglich als Text und als PseudoCode.

Gruß
Juy Juka

09.10.2009 - 23:32 Uhr

Hallo sth_Weird, Hallo NeuroCoder,

Das Thema mit dem Ausgelagerten Model neben den anderen Schichten wurden in folgendem Thread ausführlichst besprochen:
3-Schichten-Design?? [harte vs. weiche (Daten-)Objekte / OOP vs. ActiveRecods]

Gruß
Juy Juka

08.10.2009 - 17:47 Uhr

Hallo sth_Weird,

NeuroCoder hat absolut recht.
Die Präsentationsschicht (User Interface = UI) kennt die Funktionsschicht (Business Layer = BL) und diese wiederum die Datenzugriffsschicht (Data Access Layer = DAL), jeweils über Interfaces.


public class Wizzard : ...
{
  ...
  {
    this.DataBindings.Add("BackColor",this.funktionsSchicht,"WizzardBackColor");
  }
}

Aber das ist natürlich kein besonders gutes Beispiel, da die BackColor normal nichts mit der Funktionsschicht zutun hat. Hast du vielleicht ein "echtes" Beispiel?

Gruß
Juy Juka

08.10.2009 - 09:56 Uhr

Hallo sth_Weird,

Zeig uns doch mal wie deine Funktionsschicht aussieht. Es gibt hier verschiedene Arten es aufzubauen und ich glaube deine Verwirrung beruht auf dem Aufbau der Funktionsschicht.

Gruß
Juy Juka

05.10.2009 - 15:40 Uhr

Hallo winSharp93,

Im EventLog hab ich leider nichts brauchbares gefunden, nur folgendes:


Ebene		Datum und Uhrzeit		Quelle			Ereignis-ID	Aufgabenkategorie
Informationen	05.10.2009 14:52:39	Windows Error Reporting	1001		Keine
	>Fehlerbucket 125290251, Typ 5
	>Ereignisname: NetworkDiagnosticsFrameworkV2
	>Antwort: Keine
	>Cab-ID: 0
Informationen	05.10.2009 14:52:38	Windows Error Reporting	1001		Keine
	>Fehlerbucket 125290251, Typ 5
	>Ereignisname: NetworkDiagnosticsFrameworkV2
	>Antwort: Keine
	>Cab-ID: 0
Informationen	05.10.2009 14:52:38	Windows Error Reporting	1001		Keine
	>Fehlerbucket 125290250, Typ 5
	>Ereignisname: NetworkDiagnosticsFrameworkV2
	>Antwort: Keine
	>Cab-ID: 0

Gruß
Juy Juka

05.10.2009 - 15:18 Uhr

Hallo tomas.at,

Der Oracle und der MSSql Teil sollten ja eigentlich Parallel existieren, wie ich schon im anderen Post beschrieben habe. Daher sollte man beide parallel bearbeiten können. (Wenn du änderungen an der Schnittstelle hast, die von beiden Implementationen erfüllt werden müssen, hast du halt einen BrackingChange und eine neue Major-Version.)

Das kommt auf den Client an, den man für den Commit verwendet.
Und wenn du alle 145 Projekt auf einmal hoch spielen musst, müsste ja eh etwas falsch gelaufen sein. Normal macht mein eine Trennung ja, damit man nicht alles gleichzeitig Ändern muss.
Batch es gar kein Problem, wenn der verwendet Client sich über Console steuern lässt (wir haben TortoiseSVN und da geht das).

Gruß
Juy Juka

03.10.2009 - 15:06 Uhr

Hallo Mr Evil,

Die Lösung all deiner Namens fragen => Richtlinen für Namen 😜

Wenn ich jetzt deinen User-Namen mal als "Firma" benuzte kommt folgendes herraus:

MrEvil.UI.TreeListView, MrEvil.UI
MrEvil.UI.IntegerTExtBox, MrEvil.UI

ODER

MrEvil.UI.Forms.TreeListView, MrEvil.UI
MrEvil.UI.Wpf.TreeListView, MrEvil.UI
MrEvil.UI.Forms.IntegerTExtBox, MrEvil.UI
MrEvil.UI.Wpf.IntegerTExtBox, MrEvil.UI

ODER

MrEvil.CustomControls.Forms.TreeListView, MrEvil.CustomControls
MrEvil.CustomControls.Wpf.TreeListView, MrEvil.CustomControls
MrEvil.CustomControls.Forms.IntegerTExtBox, MrEvil.CustomControls
MrEvil.CustomControls.Wpf.IntegerTExtBox, MrEvil.CustomControls

Gruß
Juy Juka

03.10.2009 - 01:32 Uhr

Hallo winSharp93,

Warum sollte ich zwei SSID haben? Ich will mein existierendes WLAN (mit SSID, Verschlüsselung, Verschlüsselungs-Key, IP-Konfiguration, etc.) erweitern.

Gruß
Juy Juka

03.10.2009 - 01:22 Uhr

Hallo iAlex,

  • Du möchtest also, dass ein Entwikler (RPG Autor) deine *.exe einfach einem User gibt und dieser User dann das Programm (RPG) herrunter läd.
  • Damit es schön einfach ist soll alles in einer Datei (*.exe) drin sein.

Wenn das so ist:
Kommst du nicht um irgend eine Art der Änderung and der *.exe herrum (was immer irgend wie am besten als "compilieren" zu bezeichnen wäre).
Da gibt es viele möglich keiten, ich liste mal die auf, die mir einfallen (von einfach zu schwer):

  1. Neu Kompilieren (tjoa. 0815)
  2. Die neue Klasse in eine eigene *.dll kompilieren und diese *.dll und die *.exe mittels NETZ in eine *.exe vereinen (die *.exe muss die *.dll dann natürlich automatisch und ohne den *.dll-Namen zu kennen finden, gibt's aber alle schon hier im Forum (irgend wo))
  3. Resource-Datei in der *.exe "embedden" und diese Resouce-Datei dann in der *.exe ändern
  4. Den IL-Code der *.exe ändern (wird dann aber noch mal um ein Vielfaaches kompliziert wenn dann Sicherheit, Autentifizierung, Signierung und Co. mit ins Spiel kommen (gibt's aber auch hier im Fourm).

Aber trozt allem würde das ganze eh nur laufen, wenn eine CLR installiert ist (also unter Windows .NET).

Gruß
Juy Juka

03.10.2009 - 01:11 Uhr

Hallo,

Also wir haben mehrere Repositories:

  1. Ein Repository für alle *.sln-Dateien und alle Dokumente/Dateien die auf diese Ebenen gehören (die also direkt in die *.sln-Datei eingebunden sind und nicht in eine *.csproj (oder Eintsprechung))

  2. Ein Repository für jede *.csporj-Datei (oder Entsprechung)

  3. Ein Repository für alle Binärdateien (in allen Major- und Minor-Versionen)

  4. haben wir, da diese Daten relativ kein sind und vom Management/Marketing/PR-Abteilung/usw. verwendet wird und die nicht im Quell-Code herum spielen sollen, aber Ihre Änderungen auch dokumentiert sein sollen (und evtl. auch in die *.sln einfliesen).

  5. jedes "Projekt" aus dem eine Assembliy entsteht hat ein Repository, da das Repository in SVN eine gemeinsam "Versionsnummer" (aka. Revisionsnummer) hat und in .Net die kleinste Versionierbare ein heit das Assembly ist.

  6. haben wir, weil wir so viele Parallele Installationen mit verschiedenen DLLs in verschiedenen Versionen haben, dass wir für Support-Fälle alle Major- und Minor-Versionen gleichzeitig brauchen ( 🙁 )

Dazu Verwante und eventuell nützliche Themen:
Quellcodeverwaltung mit Subversion
Ordner- und Namespacestruktur
Ordner- und Namespacestruktur

Zum zweiten Punkt mit den Branches:
Wenn du zwei Varianten einer "Funktion" hast, die du parallel anbietest, aber beide nicht im gleichen Quellcode sind, hast du eigentlich einen Design fehler. Beide "Funktionen" sollten das selbe interface implementieren und bei der Verwendung ausgetauscht/eingesetzt werden können.
=> Das heißt für dein Beispiel, dass ein PlugIn nicht weiß mit welche Implementation des Datenzgriffs (Oracle oder MSSQL) es arbeitet und beide parallel im SVN enthalten sind (in verschiedenen Namespaces).

Gruß
Juy Juka

02.10.2009 - 00:33 Uhr

Hallo Leute,

Kennt sich irgend wer mit dem Fritz!WLAN Repeater N/G aus?
Ich hab alles was ich finden konnte eingestellt (SSID, WEP-Schlüssel, DHCP), jedoch kann man sich jetzt nicht mehr mit dem WLAN verbinden, so bald der Repeater aktiv ist (war man vorher mit dem WLAN verbunden wird man nicht getrennt).

Gruß
Juy Juka

21.09.2009 - 13:25 Uhr

Hallo Jedda2209,

Wenn man in eine ComboBox einen Wert rein schreibt, der nicht in der Auflistung enthalten ist, kann man diesen Wert nur über das Text-Property abrufen.

Gruß
Juy Juka

18.09.2009 - 12:06 Uhr

Hallo ronny75,

Die BindingList implementiert die benötigten Methoden nicht, siehe auch Suche: Beste Implementation von BindingList<>.ApplySortCore

Gruß
Juy Juka

17.09.2009 - 13:22 Uhr

Hallo Chaosmaster,

Bitte, schön das ich helfen konnte.

Gruß
Juy Juka

17.09.2009 - 11:37 Uhr

Hallo Chaosmaster,

Ehr so:


  public interface IDriverInterface
  {
    ComDriver ComDriver { get;} // wobei es besser wäre nur die benötigten Funktionen offen zulegen und nicht das ganez ComDrive-Objekt
    bool Data { get;}
  }

  public class Device
  {
    private bool _Data;
    private ComDriver _Driver;
    private List<Channel> _Channels;
    private ReadOnlyCollection<Channel> _ChannelsReadOnly;

    protected List<Channel> CoreChannels
    {
      get
      {
        if (this._Channels == null)
        {
          this._Channels = new List<Channel>();
        }
        return this._Channels;
      }
    }

    public ReadOnlyCollection<Channel> Channels
    {
      get
      {
        if (this._ChannelsReadOnly == null)
        {
          this._ChannelsReadOnly = new ReadOnlyCollection<Channel>(this.CoreChannels);
        }
        return this._ChannelsReadOnly;
      }
    }

    public bool Data{get{return this._data;}set{this._data = value;}}

    public Channel CreateChannel()
    {
      Channel c = new Channel(new DriverInterface(this));
      this.CoreChannels.Add(c);
      return c;
    }

    private class DriverInterface : IDriverInterface
    {
      private Device d;
      public DriverInterface(Device d) { this.d = d; }

      public ComDriver ComDriver
      {
        get { return d._Driver;}
      }

      public bool Data
      {
        get { return d.Data;}
      }

      #endregion
    }
  }

  public class Channel
  { 
    private IDriverInterface _driver;

    public Channel(IDriverInterface driver)
    {
      this._driver =driver;
    }

    public void Do()
    {
      this._driver.ComDriver.Do();
    }
  }

Gruß
Juy Juka

17.09.2009 - 09:06 Uhr

Hallo florian.reischer,

Gut dass du es gelöst bekommen hast.
Eine Frage hab ich aber: Warum einen eigenen TypeConverter implementieren? Es gibt doch ExpandableObjekctTypConverter (oder so ähnlich).

Gruß
Juy Juka

17.09.2009 - 09:02 Uhr

Hallo Chaosmaster,

Aus meiner sicht sieht das relativ sauber aus, wenn du beide Objetke (Device und ComDriver) übergibst. Falls es dir aber wirklich garnicht gefällt gäbe es noch folgende Lösungsanästze:

  1. Du verpasst dem Channel das Data-Property und das DataProperty des Device ändert die Data-Properties der Channel-Objekte mit.
  2. Du erweiterst Device um die benötigten Methoden um den ComDriver von außen zu benutzen.
  3. Du schreibst ein Interface, welches alle benötigten Member von Device und ComDriver enthält und eine Implementation innerhalb von Device und übergibst dies wiedrum an das Channel-Objekt.
  4. Du verpackst den zugriff auf Data in einen Delegaten und übergibst diesen zusammen mit dem ComDriver-Objekt an den Channel.

2 und 3 sind hierbei besser Lösungen, da sie die Kapselung weniger aufweichen und weniger Abhänigkeiten schaffen (3 soger abhänigkeiten reduziert).

Gruß
Juy Juka

16.09.2009 - 09:08 Uhr

Hallo florian.reischer,

Eventuell kann der Editor keine Instanzen der eizufügenden Objekte erstellen. Welche Klassen verwendest du als Key bzw. Value.
Ob man ein Dicitionary überhaupt mit diesem Editor bearbeiten kann, kann ich jetzt nicht mal genau sagen.
Am Einfachsten wäre es, wenn du deinen eigenen Editor dafür bastelst.

Gruß
Juy Juka

14.09.2009 - 08:09 Uhr

Hallo,

Never Winter Nights 2 ist .Net und definitv kommerziell. bereut reut das Geld ausgegeben zu haben

Gruß
Juy Juka

11.09.2009 - 18:05 Uhr

Hallo Lector,

Zu einem Event soll man laut Microsoft immer ein On...-Methode schreiben, wodurch diese Meldung vom Compiler nicht auftritt. (Leider kenn ich keinen Link in der MSDN dazu, wenn den jemand hat, immer her damit):


public event EventHandler<?> XXX;

protected virtual void OnXXX(? e)
{
  EventHandler<?> h = this.XXX;
  if(h!=null)
  {
    h(e??new ?());
  }
}

Gruß
Juy Juka

11.09.2009 - 18:02 Uhr

Hallo vbprogger,

public void DerEventhandler(object sender, ... e)  
{  
  if (((neededControlClass)sender).Name.Equals("bla"))  
  {  
      // do something  
   }  
}  

Warum hast du hier den Name verwendet? Das ist in fast allen Fällen nicht gut.

Gruß
Juy Juka

11.09.2009 - 13:19 Uhr

Hallo ill_son,

Das ganze kannst du unter dem Stichwort Delegat in der MSDN nachlesen :rtfm: .
Aber in Kürze:


...
meinObjek.MeinEven += DerEventhandler; // Eventhandler zuordnen
...
meinObjek.MeinEven -= DerEventhandler; //Eventhandler weg nehmen
...
public void DerEventhandler(object sender, ... e)
{
  // hier kannst du dann per Cast von sender an das Entsprechende Objekt kommen.
}

Gruß
Juy Juka

03.09.2009 - 15:16 Uhr

Hallo Kostas,

Ein switch wird nicht funktionieren, steht auch schon in der MSDN.
Aber Alternativ kannst du die Verarbeitung auch in Klassen auslagern, die alle von einem Interface erben und die Instanzen davon dann mit einer Schleife durchlaufen (was dir jeglichen if oder switch erspart):


public interface IVerarbeitung
{
  void Verarbeiten(object obj);
}

public class Verarbeitung<T> : IVerarbeitung
  where T : class
{
  public Action<T> Aktion{get;set;}

  public Verarbeitung(){}
  public Verarbeitung(Action<T> aktion):this(){this.Aktion=aktion;}

  public virtual void Verarbeiten(object obj)
  {
    T t = obj as T;
    if(t!=null && this.Aktion!=null)
    {
      this.Aktion(t);
    }
  }
}

...
IVerarbeitung[] liste = new IVerarbeitung[]{
  new Verarbeitung<_Remark>(delegate(_Remark rm){/*dies wird dann nur für _Remark-Objekte aufgerufen*/}),
  /*Hier kannst du dann weiter Verarbeitungen einfügen, für andere Klassen*/
  ...
}
...
foreach(IVerarbeitung v in liste)
{
   v.Verarbeiten(tr.Tag);
}
...

Ich empfehle dir die Richtlinien für Namen von Microsoft.

Gruß
Juy Juka

03.09.2009 - 10:48 Uhr

Hallo,

@Aurion: Wo kommt dieses Bild her?

Mein Desktiop hat auch mal wieder ein neues Motiv und das muss ich einfach mit euch teilen.
(Ich hab mir mal erlaubt den leeren zweiten Bildschirm abzuschneiden.)

Gruß
Juy Juka

28.08.2009 - 17:35 Uhr

Hallo leb0rtran,

Es gibt doch für sowas System.Collection.Spezialized.SpezializedStringCollection.

Gruß
Juy Juka