2009-03-12 12 views
3

Beliebige Verwendung von nHibernate mit einem Domain-Objekt & DTO-Objekt von einer gemeinsamen Schnittstelle implementiert? Ich versuche, alle meine nHibernate-Attribute in das Domain-Objekt zu trennen, wobei meine DTOs und die Schnittstelle sauber bleiben.nHibernate (mit Castle ActiveRecord) mit C# -Schnittstellen (speziell für DTOs)

Das Problem kommt mit nHibernate werfen Fehler, wenn es versucht, die Schnittstellen mit den konkreten Klassen zuzuordnen.

NHibernate.MappingException: Verein Referenzen unmapped Klasse: IContact

Ich verstehe, warum sein über die Verwendung des nicht-hibernated Schnittstelle beschweren, aber ich bin zu kämpfen, um visuellen einen Weg, um sie zu restrukturieren. Eine Skelett-Reproduktion meines Codes ist wie folgt dargestellt, irgendwelche Ideen, wie ich meinen Code besser strukturiere?

public interface ICompany 
{ 
    IList<IContact> Contacts { get; set; } 
} 

public class CompanyDTO : ICompany 
{ 
    private IList<IContact> contacts; 
    public IList<IContact> Contacts { get { return this.contacts; } set { this.contacts = value; } } 

} 

[ActiveRecord] 
public class Company : ActiveRecordBase<Company>, ICompany 
{ 
    private IList<IContact> contacts; 
    [HasMany(Inverse=true, Table="Contact", ColumnKey="CompanyId")] 
    [ScriptIgnore] 
    public IList<IContact> Contacts { get { return this.contacts; } set { this.contacts = value; } } 
} 

Edit:

ich eine gemeinsame Schnittstelle zu wollen, so dass ich sicher, dass sie die gleichen Felder halten (. Dh auf der Compiler lehnt sie konsistent zu halten). Es ermöglicht mir auch, die DTOs im Ansichtsteil meiner Anwendung zu verwenden, aber sie auf Domänenobjekte für den Geschäfts- und Datenzugriff zu übertragen. Die Lösung von Alex funktioniert auch nicht, weil die Kontakte von ICompany vom Typ IList und nicht von IList sind. Ich möchte es als IContact beibehalten, damit mein DTO-Objekt das Contact Domain-Objekt nicht kennt.

Antwort

4

In Ihrem konkreten Fall sollten Sie fügen Sie einfach Type = typeof(Contact) zum Mapping Attribute, etwa so:

[HasMany(Inverse=true, Table="Contact", ColumnKey="CompanyId", Type=typeof(Contact))] 
+0

Hej, wissen Sie, wie man das auch mit Fluent macht? :) – asgerhallas

+0

+1 Vielen Dank – IamStalker

0

Nun, in Ihrer Domäne können Sie nicht den IContract verwenden, um auf Ihre Domain-Entity zu verweisen, sondern stattdessen die Concrete-Klasse. Wenn Sie Ihre Version korrigieren möchten einfach:

[ActiveRecord] 
public class Company : ActiveRecordBase<Company> 
{ 
    private IList<Contact> contacts; 
    [HasMany(Inverse=true, Table="Contact", ColumnKey="CompanyId")] 
    [ScriptIgnore] 
    public IList<Contact> Contacts { get { return this.contacts; } set { this.contacts = value; } } 
} 

Ich sehe den Punkt nicht Ihre Domain und Ihre DTOs zu verbinden. Sie sind gekoppelt, und sie können nicht dieselben Informationen haben. Zum Beispiel könnten Sie einige Informationen sehr gut in Ihre Domain eingekapselt halten und nur wenige andere Informationen mitteilen. DTO wird erstellt, um die Daten, die Sie mit Up-Layern teilen möchten, zu übertragen.

Sie können die Basisklasse verwenden, um Ihre Entität und Ihr ValueObject zu definieren. Kurz: Entity: DomainEntity sind ID-fähig, dh sie können persistiert werden. ValueObject = DTO kann nicht beibehalten werden (nicht-ID können)

Blick auf die Core-Design von Sharp-Bogen:

  • /BaseObject.cs: Stellt grundlegende Aufgabe Vergleichsdienste.
  • /Entity.cs: Stellt ein Objekt mit einer Domäne Signatur und einer typisierbaren ID-Eigenschaft bereit. Dies hat auch die Validierung Unterstützung von NHibernate Validator. Objekte, die von der Entität ausgehen, MÜSSEN mindestens eine [DomainSignature] -Eigenschaft haben; Es wird eine Design-By-Contract-Ausnahme ausgelöst, wenn dies verletzt wird. Die Schnittstelle IEntityWithTypedID können Sie Ihre eigenen rollen.
  • /ValueObject.cs: Dies ist ein Wertobjekt, bei dem alle -Eigenschaften verwendet werden, wenn sie mit einem anderen Wertobjekt verglichen werden. Objekte , die sich von ValueObject erstrecken, dürfen keine [DomainSignature] Eigenschaften haben; es wird eine Design-By-Contract-Ausnahme ausgelöst, wenn dies verletzt ist.
+0

Ich möchte eine gemeinsame Schnittstelle haben, so dass ich sicherstellen kann, dass sie die gleichen Felder behalten (dh an den Compiler lehnen, um sie konsistent zu halten). Es ermöglicht mir auch, die DTOs in der Ansicht Teil meiner Anwendung zu verwenden, aber sie für Geschäfts-und Datenzugriff Domain-Objekte – mwjackson

+0

Ihre Lösung funktioniert auch nicht, weil ICompany Kontakte vom Typ IList , nicht IList ist. Ich möchte es als IContact beibehalten, damit mein DTO-Objekt das Contact Domain-Objekt nicht kennt. – mwjackson

+0

Entschuldigen Sie die Änderung Entfernen der Schnittstellenimplementierung – alexl

0

Und was soll ich tun, wenn ich [HasMany] zuschreiben? Es hat eigentlich keinen Eigenschaftsnamen 'Typ', aber [Eigenschaft] und [BelongsTo] Einsen haben.

UPDATE

Die Antwort ist CollectionType = typeof(YourType)

UPDATE 2

Nein zu verwenden, es funktioniert nicht, wird diese Eigenschaft für die Sammlung Typ festgelegt, dh Liste usw. Der Versuch, [HasMany (typeof (meType), ...)] einzustellen, funktioniert aber immer noch nicht.

Verwandte Themen