2 Stimmen

Ninject mit Objektinitialisierern und LINQ

Ich bin neu bei Ninject, so dass das, was ich versuche, vielleicht nicht einmal möglich ist, aber ich wollte fragen. Ich habe das untenstehende freihändig geschrieben, daher kann es Tippfehler geben. Sagen wir, ich habe eine Schnittstelle:

public interface IPerson
{
    string FirstName { get; set; }
    string LastName { get; set;}

    string GetFullName();
}

Und einen Beton:

public class Person : IPerson
{
    public string FirstName { get; set; }
    public string LastName { get; set; }

    public string GetFullName()
    {
        return String.Concat(FirstName, " ", LastName);
    }
}

Was ich gewohnt bin zu tun, ist etwas wie dies, wenn ich Daten aus Arrays oder Xml abrufen:

public IEnumerable<IPerson> GetPeople(string xml)
{
    XElement persons = XElement.Parse(xml);

    IEnumerable<IPerson> people = (
        from person in persons.Descendants("person")
        select new Person
        {
            FirstName = person.Attribute("FName").Value,
            LastName = person.Attribute("LName").Value
        }).ToList();

    return people;
}

Ich möchte den Beton nicht auf diese Weise fest an die Schnittstelle koppeln. Ich habe keine Informationen zur Verwendung von Ninject mit LINQ to Objects oder mit Objektinitialisierern finden können. Vielleicht suche ich an den falschen Stellen, aber ich habe jetzt einen Tag lang gesucht, ohne Erfolg.

Ich habe überlegt, den Kernel in eine Singleton-Instanz zu setzen und zu sehen, ob das funktionieren würde, aber ich bin nicht sicher, dass es plus ich gehört habe, dass die Weitergabe Ihres Kernels um eine schlechte Sache ist. Ich versuche gerade, dies in einer Klassenbibliothek zu implementieren. Wenn dies nicht möglich ist, hat jemand irgendwelche Beispiele oder Vorschläge, was die beste Praxis in diesem Fall ist? Vielen Dank im Voraus für die Hilfe.

EDITAR: Aufgrund einiger Antworten sollte ich das klarstellen. Ja, das obige Beispiel scheint kurzlebig zu sein, aber es war nur ein Beispiel für ein Stück, das ich zu tun versuchte. Lassen Sie uns ein größeres Bild geben. Nehmen wir an, dass ich anstelle von XML alle meine Daten über einen Webservice eines Drittanbieters erhalte und ich eine Schnittstelle dafür erstelle. IPerson könnte sowohl für das Person-Objekt als auch für ein User-Objekt verwendet werden. Ich werde dies innerhalb einer separaten Klassenbibliothek tun, weil es portabel sein muss und in anderen Projekten verwendet werden wird, und die Übergabe an eine MVC3 Webanwendung und die Objekte werden auch in Javascript verwendet werden. Ich schätze alle Beiträge so weit.

2voto

Tahbaza Punkte 9385

Haben Sie mehr als eine Implementierung Ihrer IPerson (Ich bezweifle es, da es scheint, dass Person ist einfach ein Datenobjekt, das weitergereicht wird). Vielleicht verstehe ich den Sinn Ihrer Frage nicht, aber DI ist für die Trennung von Belangen und die Abstraktion der Implementierung vom Schnittstellenentwurf.

Ich verstehe nicht, wie DI Ihnen helfen kann, eine Person Objekt aus einem definierten XML-Schema. Sie parsen Daten und injizieren nicht dynamisch eine Implementierung. Wenn Sie das XML auf andere Weise parsen wollten, um die Leistung zu vergleichen, würden Sie vielleicht alternative Implementierungen der Klasse erstellen, die GetPeople aber ich sehe nicht, dass das der Sinn Ihrer Frage ist.

0voto

Brandon Moore Punkte 8322

Normalerweise würde ich einfach davon ausgehen, dass jeder, der hier mehr als 20.000 Mitglieder hat, wahrscheinlich mehr über diese Dinge weiß als ich. Allerdings scheint es mir auch, dass:

1) Ihr Beispiel ist nicht allzu weit von den Beispielen entfernt, die auf der Ninject-Website verwendet werden
2) Selbst wenn "dieses" Beispiel nicht gut ist, geht es um die Verwendung von Objektinitialisierern, und das könnte für jede andere Reihe von legitimen Szenarien gelten.

Leider habe ich keine Antwort darauf, wie man die Objektinitialisierung mit Ninject durchführt, aber ich habe einen Vorschlag, wo man Ninject verwenden kann, der helfen könnte (und mir ist klar, dass dieser Beitrag ein Jahr alt ist, aber vielleicht hilft das ja jemandem).

Ich stimme zu, dass Sie höchstwahrscheinlich die konkreten Klassen in der GetPeople()-Methode verwenden sollten, da diese Methode wahrscheinlich Teil einer Implementierung ist, die spezifisch für Person ist (und wahrscheinlich in derselben Assembly und/oder demselben Namespace liegt). Wenn Sie jedoch etwas wie ein Formular haben, das einem Benutzer Informationen über eine Person präsentiert, dann sollte es meiner Meinung nach mit IPerson und nicht mit der konkreten Implementierung funktionieren.

Der Ort, an dem Sie hauptsächlich die Objektinitialisierer verwenden müssen, um die Vorteile von Linq zu nutzen, ist jedoch in Methoden wie GetPeople, wo Sie mit den konkreten Klassen arbeiten sollten, also glaube ich, dass Sie in der Lage sein sollten, das Beste aus beiden Welten zu haben. Nein, Sie könnten keinen Objektinitialisierer im Formular verwenden, wenn Sie mit einer IPerson arbeiten, aber ich glaube nicht, dass Sie das jemals "müssen", wenn Sie Linq in der GetPeople-Methode verwenden möchten.

Edit: Eigentlich "brauchen" Sie keine Objektinitialisierungen, um Linq hier zu verwenden

Wenn Sie auf syntaktischen Zucker verzichten, können Sie Folgendes umschreiben

IEnumerable<IPerson> people = ( 
    from person in persons.Descendants("person") 
    select new Person 
    { 
        FirstName = person.Attribute("FName").Value, 
        LastName = person.Attribute("LName").Value 
    }).ToList(); 

Als

IEnumerable<IPerson> people = 
    (persons.Descendants("person")
           .Select(o => 
           { 
               var p = new Person();
               p.FirstName = person.Attribute("FName").Value;
               p.LastName = person.Attribute("LName").Value;
               return p;
           }).ToList();

Und Sie können sehen, wie einfach das mit der Injektion funktionieren kann.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X