Laden...

Forenbeiträge von serial Ingesamt 902 Beiträge

19.11.2013 - 14:07 Uhr

Hi,

also das Ausmaß war mir nciht klar. Aber der Hintergrund:

Ich arbeite in einem Projekt, wo für Logeinträge die Entities mit ihren Werten geloggt werden (im Falle eines Fehlers). Nun führt dies oft zu Problemen mit Lazyloading, sodass sich die Entwickler hier entschlossen haben, vor dem Loggen einfach die Entity nochmal zu laden, mit allen Informationen die für das Logging gebraucht werden. Dies führte oft dazu, dass neue Entwickler einfach vergessen haben die nötigen Includes anzugeben etc. Nun war mein erster naiver Gedanke, dies zu automatisieren. Das es kein best practise ist, ist mir klar 😕

mfg
serial

19.11.2013 - 13:50 Uhr

HI,

@Abt: ja sorry ich spreche vom EF, meine Gedanken waren in einem anderen Kontext.

Das es kein 3 Zeiler wird ist mir klar, allerdings kenne ich mich zu wenig mit Expressions aus, um das ohne einen Anstoß hinzubekommen. Und genau das Include via Lambda will ich ja nutzen, dafür möchte ich mir ja für jede property welche es nachzuladen gilt, automatisch ein Lambda erzeugen um dies dann EF zu übergeben.

mfg
serial

19.11.2013 - 13:43 Uhr

HI,

danke schonmal. Also der rekursive aufruf erfolgt, allerdings immer auf das übergebene kind element. (logischerweise).

Was will ich erreichen?

Ich möchte eine MEthode anbieten, welche es erlaubt für eine Linq2Sql-Abfrage alle Includes implizit per Ebenen anzugeben. Also das alle Properties bis zu einer gewünschten Tiefe gleich geladen, und nicht nachgeladen werden. Ich hoffe das habe ich verständlich ausgedrückt.

mfg
Serial

18.11.2013 - 17:12 Uhr

Hallo,

ich möchte, zur vereinfachung von Linq2SAQL-Includes, eine Methode schreiben, welche alle Properties einer Entity als Expression zurückgibt. Dabei sollen auch auf Navigationseingeschaften zugegriffen werden (für Eager-Loading).

Als Beispiel soll folgender Code dienen (nicht sinnvoll, ich weiss)


public class Person
    {
        public Person()
        {
            Adresses= new List<Adress>();
        }

        public string Name { get; set; }
        public int Age { get; set; }
        public IList<Adress> Adresses { get; set; }
        public IList<string> Names { get; set; }
        public City City { get; set; }
    }

    public class Adress
    {
        public string Street { get; set; }
    }

    public class City
    {
        public string Name { get; set; }
        public IList<string> Plz { get; set; }
    }

Als Ergebnis würde ich mir dann eben Wünschen:

entity => entity.Adresses;
entity => entity.City;
entity => entity.City.Plz;

folgenden Code habe ich:


public class PropertyExtractor
    {
        public IEnumerable<Expression> GetNavigationProperties<T>(T entity, int level)
        {
            var entityType = entity.GetType();
            var result = GetNavigationPropertiesInternal(entityType, level, 0);
            return result;
        }

        public IEnumerable<Expression> GetNavigationPropertiesInternal(Type entityType, int maxDepth, int currentDepth)
        {
            var result = new List<Expression>();
            foreach (var propertyInfo in entityType.GetProperties(BindingFlags.Instance | BindingFlags.Public))
            {
                if (propertyInfo.PropertyType.IsPrimitive || propertyInfo.PropertyType == typeof(string))
                    continue;

                //here we have to concat the parent-accessor
                var parameter = Expression.Parameter(entityType, "entity");
                var property = Expression.Property(parameter, propertyInfo);
                var funcType = typeof(Func<,>).MakeGenericType(entityType, propertyInfo.PropertyType);
                var lambda = Expression.Lambda(funcType, property, parameter);
                if (currentDepth <= maxDepth)
                {
                    Type type = ListArgumentOrSelf(propertyInfo.PropertyType);
                    foreach (var info in GetNavigationPropertiesInternal(type, maxDepth, currentDepth++))
                        result.Add(info);
                }
                result.Add(lambda);

            }
            return result;
        }

        public Type ListArgumentOrSelf(Type type)
        {
            if (!type.IsGenericType)
                return type;
            if (type.GetGenericTypeDefinition() != typeof(IEnumerable<>) && !typeof(IEnumerable).IsAssignableFrom(type))
                throw new Exception("Only IEnumerable<T> are allowed");
            return type.GetGenericArguments()[0];
        }

    }

allerdings komme ich da nur auf die erste Ebene, nciht auf die 2te:
entity => entity.City.Plz.

HAt jemand eine Idee für mich?

Danke =)

mfg
Serial

22.07.2013 - 16:16 Uhr

Hallo MarsStein,

danke für die Antwort. DAs macht natürlich Sinn.
Wie kann ich allerdings die Rows/Columns für die Eingabefelder der Tage erstellen, da die Columns dieser Felder dynamische Namen haben, welche mir nicht bekannt sind um die per Bind im Template zu verwenden.

mfg
serial

22.07.2013 - 13:03 Uhr

Hallo,

ich wollte mal wissen, welches Control aus eurer Sicht für die Struktur im Dateianhang am besten geeignet ist?

Alle Dropdownlisten werden mit Daten gefüllt und müssen pro Column unterschiedliche Daten zulassen.
Die ersten 4 Rows sind immer statisch, darunter die Tage können 0-n Rows sein.

Bis jetzt ist mir, bis auf das Zusammenbauen einer eigenen Tabelle nichts weiter eingefallen, da die anderen Controls alle Columnbezogen arbeiten. Vielleicht hat ja jemand eine gute Idee.

mfg
serial

13.05.2013 - 17:27 Uhr

Hi,

und wenn man das overflow deaktiviert, und das Toolstrip sich autopmatisch in der Größe anpassen lässt?

mfg
serial

08.05.2013 - 13:10 Uhr

HI,

wo ist das Problem? Ich denke DirectoryInfo oder Directory sind deine Freunde.

mfg
Serial

01.05.2013 - 20:42 Uhr

Hi,

du kannst im VS eine Start-form festlegen. Diese wird dann auch angezeigt wenn VS startet. Solltest du dann in dieser Form im Konstruktor oder im Load-Event etwas machen, zB eine textbox anzeigen, wird diese auch im VS angezeigt (da auch der Designer diese aufruft).

Umstellen kannst du das in den Projekteigenschaften.

mfg
serial

01.05.2013 - 20:39 Uhr

Hi,

wenn das Schema immer gleich bleibt, kannst du theoretisch eine Route definieren, z.B:


routes.MapRoute(
    "kategorieRoute", // Route name
    "{controller}/{maincategory}/{subcategory}/{subcategory2}", // URL mit parameter
    new { controller = "Games", action = "Find", maincategory= "all", subcategory = "action", subcategory2 = UrlParameter.Optional } 
);

Damit hast du dann einen Controller Games, mit der Methode Find, und diese würde die Kategorien dann als Parameter bekommen.

Wichtig ist hierbei natürlich die reihenfolge der routen, wenn du mehrere hast.

Beispielurl wäre dann:

Games/PS3/Action/Singleplayer --> alle Params
Games/PC/Sport --> Subcategory 2 bleibt leer
Games/XBOX/ --> Subcategory = action
Games/ --> maincategory = all, Subcategory = action

mfg
serial

26.04.2013 - 10:09 Uhr

Welche Kommentare meinst du?
Einfache XML Kommentare, oder XSD-Documentation-Kommentare?

mfg
serial

26.04.2013 - 10:06 Uhr

Hallo,

bei Entity gehe ich mal von EntityFramework aus.
Also wenn die Daten immer zusammengehören, kannst du entweder ein EF-Model erzeugen, welches die Eigschaften hat und aus den beiden Tabellen gefüllt wird, oder du schreibst die selbst eine Klasse.

Insgesamt kommt es natürlich darauf an, was du noch alles vor hast. Aber wenn du die Relationen (wenn in der DB welche vorhanden) richtig ansprichst, kannst du eigentlich auch mit deiner Vorgehensweise die UI füllen.

mfg
serial

23.04.2013 - 15:18 Uhr

Hallo,

du kannst auch Intersect in Verbindung mit einem IEqualityComparer verwenden.


class Program
    {
        static void Main(string[] args)
        {
//Simuliert die CSV-Zeilen der beiden Dateien
            List<string[]> lines1 = new List<string[]> { new string[] { "1", "2", "3" }, new string[] { "2", "3", "4" } };
            List<string[]> lines2 = new List<string[]> { new string[] { "1", "2", "3" }, new string[] { "2", "3", "5" } };


            List<string[]> result = lines1.Intersect(lines2,new MyComparer()).ToList();

            Console.WriteLine(result.Count);
            Console.ReadLine();
        }
    }

//Die beiden Methoden müsstest du eben konform ausprogrammieren
    class MyComparer : IEqualityComparer<string[]>
    {
        public bool Equals(string[] x, string[] y)
        {
            if (x.Length != y.Length)
                return false;
            return x[0] == y[0];
        }

        public int GetHashCode(string[] obj)
        {
            return obj[0].GetHashCode();
        }
    }

mfg
Serial

18.04.2013 - 12:09 Uhr

Hallo,

wie validierst du? Auf einem XMLReader oder Document?
Vielleicht ist der Key in einem optionalen Element verschachtelt?

mfg
Serial

18.04.2013 - 12:07 Uhr

Wenn du an keine Informationen weiter herankommst, was fehlgelaufen ist, stellt sich die frage, ob du das programm noch ändern kannst, um zB unbehandelte Ausnahmen zu loggen, um an weitere Informationen zu kommen.

mfg
Serial

19.03.2013 - 21:24 Uhr

Hi,

auch das funktioniert:


string part = "Hallo <br />";
            for (int i = 0; i < 3; ++i)
            {
                part += string.Format("{0} <br />", i);
            }
            return part;

vielleicht solltest Du mal etwas Code zeigen, vielleicht ist da der Fehler versteckt.

mfg
serial

19.03.2013 - 20:59 Uhr

Hallo,

du benutzt ja anscheinend MVC, daher solltest Du dir mal die Klasse MvcHtmlString anschauen.

Allerdings funktioniert bei mir das ohne Probleme:


 public string Index()
        {
            return "Hallo <br /> Sie";
        }

Aber auch die Googlesuche bringt viele helfende Ergebnisse.

mfg
serial

07.03.2013 - 09:54 Uhr

Hallo,

danke herbivore für den Tipp, ich habe das FormatsWith entsprechend angepasst, um genau die oben genannte Syntax zu erreichen.

Hier der Code, sollte es jemanden interessieren:


 public static string FormatWith(this string format, IFormatProvider provider, object source)
        {
            if (format == null)

                throw new ArgumentNullException("format");

            Regex r = new Regex(@"\{\{|\{([\w\.\[\]]+)((?:[,:][^}]+)?\})",
 RegexOptions.Compiled | RegexOptions.CultureInvariant | RegexOptions.IgnoreCase);

            List<object> values = new List<object>();
            string rewrittenFormat = r.Replace(format, delegate(Match m)
            {
                string propertyName = m.Groups[1].Value;

                if (propertyName.Length == 0)
                    return m.Value;

                values.Add(propertyName == "0" ? source : DataBinder.Eval(source, propertyName));

                string len = m.Groups[2].Value.Replace(",", "").Replace("}", "").Replace(" ", "").Replace(":","");
                if (!String.IsNullOrEmpty(len))
                {
                    int leng;
                    if (Int32.TryParse(len, out leng))
                    {
                        string value = values[values.Count - 1].ToString();
                        value = value.Substring(0, leng);
                        values[values.Count - 1] = value;
                    }
                }
                return "{" + (values.Count - 1) +"}";
            });
            return string.Format(provider, rewrittenFormat, values.ToArray());
        }

mfg
Serial

06.03.2013 - 12:50 Uhr

@herbivore, ja da hast du natürlich recht, andersherum =)

06.03.2013 - 12:32 Uhr

Hi Abt,

das hört sich logisch an, danke. Komm ich da auch noch einfach an die Seperatoren ran (ich kenn mich mit regex nicht wirklich aus).

@herbivore: danke, ich schau mir das mal an. Leider habe ich nur teilweise einfluss auf das pattern

mfg
serial

06.03.2013 - 12:21 Uhr

Hallo,

du musst UTF-8 verwenden (für das CSV-File).

mfg
serial

06.03.2013 - 12:11 Uhr

Hallo,

ich habe gerade ein kleines Problem, und wollte mal von euch eine elegante Möglichkeit wissen wie ich dieses lösen kann:

Ich habe ein Objekt, welches unterschiedliche Eigenschaften hat, nun soll aus den Werten dieser Eigenschaften ein string erzeugt werden. (zB Email-Adresse)

Wie die Werte verwendet werden, werden in einem Pattern dargestellt.

Beispielpattern:

{Name}.{Surename:1}

Wenn wir jetzt ein Objekt haben, welches die Eigenschaft Name mit dem Wert "Mustermann", und eine Eigenschaft Surename mit dem Wert "Max" hat, soll daraus folgendes erzeugt werden:

Mustermann.M (das :1 hinter Surename heisst, nur der erste Buchstabe)

Dieses Pattern ist dabei Flexibel, dass man auch {Surename}{Name:8} (Max_Musterma) verwenden kann, oder {Surename}{Name}.{Surename:1} (Max_Mustermann.M) etc...

Wie würdet ihr das am elegantesten abbilden? Ich dachte an Regex.Split, aber so richtig ist die Lösung noch nicht in meinen Gedanken materialisiert. Vielleicht kann mir jemand einen Denkanstoß geben 😃

mfg
Serial

01.02.2013 - 12:30 Uhr

Hi,

also wenn ich mit externen Komponenten arbeite, kapsele ich diese immer in einer C# Klasse. Würde hier auch gut mit dem MVVM zusammenpassen, indem du deine Komponente in einem ViewModel kapselst und dieses dann bindest.

mfg
serial

04.11.2012 - 00:10 Uhr

Hi,

prinzipiell kannst du natürlich das zu bearbeitende Item mitgeben, da spricht ja erstmal nichts dagegen. Was macht denn die Form noch alles? Zeigt sie auch eine Liste an? Wenn nicht, bräuchtest du die Liste ja auch nicht übergeben, sondern die Form gibt das neue Item einfach zurück, und der Aufrufer kann dann das Item hinzufügen.

mfg
serial

09.09.2012 - 18:54 Uhr

hei danke.

Wenn wirklich nur nen wrapper drüber ist, wieso bringt das control einen JS-Fehler, wohin der IE den nicht bringt?

mfg
serial

07.09.2012 - 16:17 Uhr

Hallo,

leider funktioniert dann die Seite nicht.
Welche JS-Engin benutzt denn das Control? Bzw kann man da noch irgendwie Kontrolle übernehmen?
Denn in allen Browsern bringt das selbe HTML keinen Fehler.

mfg
serial

07.09.2012 - 10:03 Uhr

Hallo MarsStein,

ich bekomme in einem Webbrowser-Control Javascriptfehler, welche mit dem gleichen HTML weder im IE, FF,Opera oder Chrome auftreten. Darum habe ich mich davon erstmal verabschiedet, da ich keine Ansatzpunkte zur Behebung der JS-Fehler habe. (das HTML ist nicht von mir erzeugt, hat aber wie gesagt in allen anderen Browsern keine Fehler, nur in dem Control)

Wenn du dazu einen Tipp hast, gern 😃

mfg
serial

06.09.2012 - 17:03 Uhr

Hallo,

ich haabe zur Laufzeit einen Process gestartet, welcher den IE öffnet. Nun möchte ich ein refresh an den geöffneten IE schicken, damit er die Seite neu lädt. Entweder seh ich den Wald vor lauter Bäumen nicht, aber ich habe noch keine Lösung gefunden.

Kann mir jemand helfen.

folgender Code:


 private  void OpenIE()
        {
            if (!String.IsNullOrEmpty(data))
            {
                if (String.IsNullOrEmpty(_file))
                {
                    _file = Path.GetTempFileName();
                    _file = Path.ChangeExtension(_file, "html");
                }
                File.WriteAllText(_file, data);
                if(_p==null)
                     _p = Process.Start(_file);
                else
                    //hier nur ein refresh senden, keinen neuen IE öffnen

            }
        }

danke
serial

31.07.2012 - 10:49 Uhr

Hallo,

nein das bedeutet, das er keine Objekte mehr erstellt.

Also folgendes einfaches (beispielhaftes) XML (auf diesem wurden Klassen erzeugt)

<Root>
 <Child1>
   <Child11 />
   <Child11 />
 </Child1>
 <Child1>
   <Child11/>
   <Child11/>
 </Child1>
</Root>

Wenn man nun deserialisiert, hab ich eben meine Rootklasse mit Liste von Child1 (oder 2 Properties, jenachdem wir Schema aussieht), und jedes Child1 eben 2 Properties von Child11.

Wenn ich das XML nun dahingehend verändere:

<Root>
 <Child1>
   <Child11 />
   <Child22 />   <---- hier ist das neue Element
   <Child11 />
 </Child1>
 <Child1>
   <Child11/>
   <Child11/>
 </Child1>
</Root>

Dann habe ich bei dem ersten Child1-Objekt nur noch die erste Child11-Eigenschaft gefüllt, und die zweite bleibt leer, weil vorher das neue Element Child22 vorkommt. Das 2te Child1-Objekt ist wieder korrekt gefüllt.

mfg
Serial

26.07.2012 - 15:29 Uhr

Hallo,

ich habe folgendes Problem:

Ich habe Code per XSD erzeugt für ein spezielles XSD-Schema. Natürlich möchte ich XML-Files in Objekte deserialisieren. Nun kann es sein, das dem Schema/und den XML-Files neue Elemente hinzugefügt werden (Schema ist aber abwärtskompatibel, also alte Files sind immer valide gegen ein neues Schema). Nun ist das Problem bei der deserialisierung, dass wenn der XmlSerializer an das neue Element im XML kommt, er aller Elemente gleicher Ebene danach nicht mehr deserialisiert. Sollte er nicht eigentlich nur das unbekannte elemente ignorieren, und danach weiter fortfahren?

Gibt es hier eine Möglichkeit für mich?

mfg
Serial

07.03.2012 - 12:02 Uhr

Hallo Leute,

ich habe folgendes Problem:

Ich habe mir aus einem XSD Code erzeugt (zum serialisieren/deserialisieren).
Nun passiert folgendes Szenario: das XSD wird geändert, aber der Code kann nicht zeitnah angepasst werden. Das programm, welches den Code verwendet soll dennoch in der Lage sein, XML-Dateien welche dem geändertem Schema entsprechen zu bearbeiten. Die Schemachanges selbst sind abwärtskompatibel, also eine alte XML-Datei ist auch für das neue Schema valide.
Nun kann es ja aber sein, dass mein generierter Code entweder zu viele Elemente hat (im neuen Chema wurden Teile entfernt) bzw zu wenige Elemente hat (im neuen Scheme gibt es neue Attribute/Elemente). Nun muss ich sicherstellen, dass wenn eine XML File geladen wird, welche dem neuen Schema entspricht, dass durch das serialisieren/deserialisieren keine Daten im XML landen, die im neuen Schema nichtmehr vorhanden sind, bzw keine daten verloren gehen, welche im neuen Scheme vorhanden sind, aber im alten Scheme (aus dem der Code generiert wurde) nicht.

Ich habe keinen Einfluss auf das XML oder Schema.

Wie kann ich diesem Problem Herr werden?

mfg
serial

16.02.2012 - 12:40 Uhr

Hallo,

möglicherweise liegt es am Viewstate, dieser behält die Daten über den REquest!
Darum sollte man ComboBoxen etc auch nur mit daten befüllen, wenn es kein PostBack ist.

mfg
serial

16.02.2012 - 12:38 Uhr

Hi winSharp93,

also ja es gibt commands welche eben zB das Hinzufügen eines Items kapseln sollen.
Diese Logik ist bis jetzt im Presenter, weil er zugriff auf das model hat.
Darum ja eben die Frage, ob das COmmand den Presenter verwenden soll, oder das Model direkt!

Das ich nciht einfach ohne Commands arbeiten kann, liegt daran, das uU viele Buttons die selbe Aktion ausführen, somit ist es mit einem Command besser. Sonst müsste jeders Control immer Presenter.Methode() aufrufen.
(Oder was meinst du mit: "Da kann man den Code des Commands IMHO auch gleich in den Presenter packen.") --> kannst du das kurz demonstrieren?

NAtürlich ist es ja eigentlich so, dass ein View einen Presenter hat, und ein Model, sodass ein anderes View normlerweise NICHT Aktionen aus einem anderen View aufruft. Aber ich habe eine Art "Schnellaktionen", welche eben Aktionen aus unterschiedlichen Views bereitstellt. Da dachte ich mir kommen Commands ganz gut.

mfg
serial

15.02.2012 - 17:37 Uhr

Hallo winSharp93,

in meinem Code steht ca soetwas:


FormLoad:

ICommand insertCommand = new InsertItemCommand(myPresenter);
CommandManager.Bind(insertCommand, insertToolStripMenuItem);
CommandManager.Bind(insertCommand, btnInsert);

mfg serial

13.02.2012 - 14:40 Uhr

Hi winSharp93,

Undo/Redo setze ich mit dem Memento direkt im Model um, da ich mit automatischer Datenbindung arbeite.

Commands sind hier hauptsächlich da, um immer wiederkehrende Aktionen zu kapseln. Also zB AddItem-Funktion. Ich erstelle das COmmand im View und übergebe den Presenter. Danach binde ich den Command an ein Control.
Du sagst, das der Presenter die Commands erzeugen sollte? MAcht er diese dann durch Properties öffentlich verfügbar?

mfg
serial

13.02.2012 - 12:17 Uhr

Hallo Kileak

Die Methode AddOrder ist narülich auch im Model, aber der Presenter hat natürlich auch eine, zum Aufruf aus der View. Also deine Meinung ist: Command arbeitet auf Model und nicht auf Presenter?

Danke

13.02.2012 - 11:29 Uhr

Hallo Leute,

ich stell mir gerade die Frage, wie ihr Command mit dem MVP-Muster umsetzt.
Nehmen wir an, ich habe eine einfache Orderview mit einem Orderpresenter, welche eben die Logik hält. Nun gibt es einen Button AddOrder, und eine korrespondierende Presentermethode AddOrder(). Diese fügt über einem Service der BL eine Order hinzu.

Nun möchte man aber nicht nur den Button, sondern noch einen Menüeintrag und einen Link welcher auch eine Order hinzufügt. Also könnte man ja das in ein Command kapseln und diesen verwenden. Nun die Frage: sollte der Command den entsprechenden Presenter bekommen, und dessen AddOrder()-MEthode aufrufen, oder sollte der Command direkt mit dem Model sprechen? Was ist wenn der Command ausserhalb der Ordersview verwendet wird? (Dann steht der Presenter theoretisch nicht zur Verfügung). Wie handhabt ihr das Szenario? Oder macht ihr das ganz anders?

Ich freue mich auf eure Antworten.

mfg
serial

24.01.2012 - 13:17 Uhr

Hallo Leute,

ich habe ein Problem mit einem Serviceaufruf.
Ich habe einen Javaservice, welcher BasisHttp Auth benutzt und über HTTP bereitsteht.
Proxy habe ich mir von VS2008 generieren lassen (WCF Proxy).

Aufrufen möchte ich ihn folgendermaßen:

RemoteClient client = new RemoteClient();
            ((BasicHttpBinding)client.Endpoint.Binding).Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
            ((BasicHttpBinding)client.Endpoint.Binding).Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
           

            client.ClientCredentials.UserName.UserName = "user";
            client.ClientCredentials.UserName.Password = "pw";
            client.ClientCredentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.Identification;
            
            var response = client.methode(new RequestObject{ id = "myId" });

Allerdings schickt der Server ein 401, und folgende Exception im VS:

Fehlermeldung:
Fehler beim Empfangen der HTTP-Antwort für
>
. Die Ursache kann sein, dass die Dienstendpunktbindung kein HTTP-Protokoll verwendet. Eine andere mögliche Ursache ist, dass der HTTP-Anforderungskontext vom Server abgebrochen wird (vermutlich auf das Herunterfahren des Diensts zurückzuführen). Weitere Informationen finden Sie in den Serverprotokollen.

Also der Server lüft und ist erreichbar, es liegt wohl an der Anmeldung. Kann mir hier jemand vielleicht helfen?

mfg
serial

18.01.2012 - 11:02 Uhr

Hallo,

genau was herbivore sagte stimmt: mir geht es um das erstellen der specifications und das verknüpfen. Die Daten werden in der BL geholt, und das Ergebnis empfängt der Presenter, welcher die Daten an das View gibt, dieses kümmert sich dann um die Anzeige (dynamische Controls erstellen).

ICh habe aber nun verstanden was FZelle meint (glaube ich): Ich denke das schon der Code zum erstellen der specifications logik ist, die bei ihm nicht ins view gehört (ausser bei einer specification, da diese über eine einfache property abgebildet werden kann). Habe ich das falsch verstanden?

Ich frage mich nur gerade, ob denn nicht eigentlich View UND Presenter eigentlich zur Ansicht gehören. BL ist, mMn, nicht im Presenter?

mfg
serial

17.01.2012 - 17:33 Uhr

HI,

also die Suchparameter werden einfach OR-Verknüpft, und dies mach ich über eine List in der die Specifications gehalten werden...dann benutzer ich die Aggregate-Methode um diese mit einer ORSpecification zu Verknüpfen. Aber das ist ja, wie herbivore sagte, keine Businesslogik, oder?

mfg
serial

17.01.2012 - 14:46 Uhr

Hi FZelle,

die Entscheidung für SupervisingController ist schon gefallen und schon umgesetzt (uA weil ich viel automatische Datenbindung an BindingLists etc verwende).

Mich würde wirklich nur interessiern, wie ich den Suchtask am "konformsten" abbilde. Das alle beschriebenen Möglichkeiten funktionieren ist klar.

mfg
serial

17.01.2012 - 12:49 Uhr

Hi,

was ist der Unterschied ob ein oder mehrere Suchparameter?
Also um das Beispiel mal etwas mit Leben zu füllen:

Ich habe eine GUI mit einem Textfeld für den Suchbegriff. Und mehrere Checkboxen für die Suchkriterien (Name, Vorname...etc).
Je nachdem welche checked sind, werden mehrere Specifications benötigt welche mit einer OR-Specification verknüpft werden. Jede Specification ist eine Klasse welche eine Expression beinhaltet. Da alle benötogten Objekte im SPeicher liegen habe ich eine Extensionmehode für IEnumerable(T) welches mehere ISpecification(T) bekommt. Die Auflistungen sind natürlich in den Domainobjekten.
Nun müssen wir also diese Specifications in die Bl bekommen. Der Presenter benutzt eine Art AggregateRoot, welches alle benötigten Objekte und Auflistungen (welche durchsucht werden müssen) beinhaltet. Somit kann der Presenter einfach an das AggregateRoot die benötiogten Specifications geben. Nur wer erstellt diese?
Wenn dies der Presenter machen will, muss er ja genau wissen welche Optionen (Checkboxen) in der View aktiviert sind --> für jede Option eine Eigenschaft! Oder das View macht dies, indem es beim Klick auf Suchen für jede Checkbox eine SPecification erstellt. Oder man kann ja auch so Sachen machen, dass die Checkbox ihre Specification als Tag mitbekommt, (so kann man dann einfach wenn neue Specifications hinzukommen dynamisch neue Checkboxen erstellen, und die Logik müsste nicht geändert werden, wenn das View einfach alle Tags ausließt). Also was findet ihr am besten?

mfg
serial

17.01.2012 - 11:58 Uhr

Ok, also ist es ligitim das das View die Specifications auswählt/erstellt und an die BL übergibt.

Danke

mfg
serial

17.01.2012 - 10:50 Uhr

Hallo,

ist das Auswählen der benötigten Specifications wirklich Businesslogik?
Denn die Auswahl kann ja nur durch die BBenutzerauswahl in der UI erzeugt werden.
Die Suche selbst wird natürlich in der BL ausgeführt, mir geht es um das zusammenbauen der Suchkritierien.

mfg
serial

P.S. es ist ein SupervisingController

17.01.2012 - 09:46 Uhr

Hallo Leute,

ich hab heute wieder mal eine Designfrage.

Man hat eine UI, wo der User dynamisch seine Suche zusammenstellen kann, also Suche nach Name, oder Vorname, oder Name und Vorname, oder Name und Straße etc...

Die Suche selbst habe ich mit einer Art des Specificationpatterns realisiert,.
Nun die Frage, wer baut die Specifications zusammen?

  • Die View und übergibt die Specifications dann dem Presenter?
  • Oder ließt der Presenter aus dem View die gewünschten Suchparameter aus und baut die Specifications selbst? (hier bräuchte man dann für jeden Suchparameter eine Eigenschaft oder irgendetwas was der Presenter auslesen kann um zu erfahren, nach was gesucht werden soll).

Wie macht ihr das in euren Projekten?

mfg
serial

22.12.2011 - 14:36 Uhr

Hallo FZelle,

verständlich 😃

Aber das View führt folgenden Code aus:


var searchResult = _presenter.FindPrev();
            if (!searchResult.Found)
                MessageBox.Show("Erste Eintrag wurde erreicht");
            else
                lblSearchCount.Text = string.Format("{0}/{1}", searchResult.CurrentSearchIndex, searchResult.SearchCount);

wie sollte der Labeltext gesetzt werden? Soll das View dennoch ganz normal das SearchResult benutzen um den Labeltext zu setzen (denn das gehört ja definitiv ins View)? Der Presenter würde dann in FOundPrev() eine Meldung an das View absetzen.

mfg
serial

22.12.2011 - 11:44 Uhr

Hi Leute,

ich würde mal interessieren, was ihr für "richtiger" haltet.
Ich habe ein normalen MVP Aufbau (Supervising oder Passive), es soll eine Suchfunktionalität implementiert werden, wo es mehrere Ergebnisse gibt, und der Benutzer im View die Ergebnisse weiterschalten kann.
Der Presenter führt die Suche aus, und gibt in der Searchmethode ein SearchResult-Objekt zurück, mit dem Count der gefunden Elemente, dem aktuellem Index und dem gefundenem Objekt.
Weiterhin hat er noch FouncNext und FoundPrev Methoden, die eben das nächste/vorherige Element suchen.

Das SearchObjekt habe ich eingefügt, weil ich in der View anzeigen ala:
"Element 1/n gefunden" anzeigen möchte.

Frage:

  • Wenn nichts gefunden wurde, soll der Presenter eine mögliche Methode ShowMessage auf dem View aufrufen, und eine Meldung zeigen, oder sollte das View das SearchResult untersuchen, und im Falle das nichts gefunden wurde selbst eine Meldung erzeugen?

mfg
serial

19.12.2011 - 15:17 Uhr

Hi,

also ist die Entscheidung, dass zB der ChildAPresenter ein Event wirft, welches vom Rootpresenter behandelt wird in Ordnung? Bzw wird dieses Event vom AppController gefangen, welcher dann eine Methode auf dem Rootpresenter aufruft (damit die beiden Presenter nicht gekoppelt sind).

mfg
serial

19.12.2011 - 10:14 Uhr

Hi FZelle,

Da wäre es dann zu überlegen, ist es eine Aufgabe des jeweiligen Parents(PresenterA/B/C), oder gehört es zum Workflow.
Kann man es evtl auch als
>
ansehen?

kannst Du mir das etwas genauer erläutern?
Ich kann die Fragen irgendwie nicht so richtig beantworten...

Also ich benutze kein CAB oder ein anderes Framework.

mfg
serial

16.12.2011 - 18:35 Uhr

Hi FZelle,

also das ist noch garnicht gelöst, da ich erstmal drüber nachdenke.
Also möglich wäre alles, ein View welches die Presenter verknüpft. Ein Appcontroller den jeder Presenter kennt, und der als Mediator zwischen den Events fungiert.

was hältst du für das sinnvollste?

mfg
serial