2009-03-12 6 views
3

Any utilisant nHibernate avec un objet Domain & Objet DTO implémenté à partir d'une interface commune? J'essaye de séparer tous mes attributs de nHibernate dans l'objet de domaine, laissant mes DTO et interface propres.nHibernate (avec Castle ActiveRecord) avec des interfaces C# (spécialement pour les DTO)

Le problème vient des erreurs de lancement de nHibernate lorsqu'il essaie d'associer les interfaces aux classes concrètes.

NHibernate.MappingException: références Association classe unmapped: IContact

Je comprends pourquoi sa plainte sur l'utilisation de l'interface non-hiberné, mais je me bats pour un moyen visuel de restructurer autour d'elle. Une reproduction squelette de mon code est présentée ci-dessous, des idées pour mieux structurer mon code?

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:

Je veux avoir une interface commune pour que je puisse assurer qu'ils gardent les mêmes champs (.-À-dire se penchant sur le compilateur pour les garder en accord). Il me permet également d'utiliser les DTO dans la partie de vue de mon application, mais les jette aux objets de domaine pour l'accès d'affaires et de données. En outre, la solution d'alex ne fonctionne pas car les contacts ICompany sont de type IList, pas IList. Je voudrais le garder comme IContact pour que mon objet DTO n'ait aucune connaissance de l'objet Contact Domain.

Répondre

4

Dans votre cas concret, vous devez simplement ajouter Type = typeof(Contact) à l'attribut de mappage, comme ceci:

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

Hej, savez-vous aussi comment faire avec Fluent? :) – asgerhallas

+0

+1 Merci beaucoup – IamStalker

0

Bien dans votre domaine, vous ne pouvez pas utiliser le contrat IC en référence à votre entité de domaine, utilisez plutôt la classe Concrete. Si vous souhaitez corriger votre utilisation de la version simple:

[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; } } 
} 

Je ne vois pas le point d'interfacer votre domaine et vos DTO. Ils sont couplés, et ils ne peuvent pas avoir les mêmes informations. Par exemple vous pouvez garder quelques informations très bien encapsulées dans votre domaine et ne communiquer que peu d'autres informations. Les DTO sont conçus pour transférer les données que vous souhaitez partager avec les couches supérieures.

Vous pouvez avoir une classe de base pour définir votre entité et votre ValueObject. En bref Entité: DomainEntity sont ID capable signifie qu'ils peuvent être persistés. ValueObject = DTO ne peut pas être persisté (non ID mesure)

Regardez la conception de base de Sharp-Arch:

  • /BaseObject.cs: Fournit des services de base objet de comparaison. /Entity.cs: Fournit un objet avec une signature de domaine et une propriété d'ID typeable. Cela a également la validation support de NHibernate Validator. Les objets qui s'étendent de l'entité DOIVENT avoir au moins une propriété [DomainSignature]; il y aura une exception de conception par contrat en cas de violation. L'interface IEntityWithTypedID vous permet de rouler les vôtres.
  • /ValueObject.cs: objet de valeur dans lequel toutes ses propriétés sont utilisées par rapport à un autre objet de valeur. Les objets qui s'étendent de ValueObject peuvent ne pas avoir de propriétés [DomainSignature] ; une exception de conception par contrat est générée si cela est enfreint.
+0

Je veux avoir une interface commune afin que je puisse m'assurer qu'ils gardent les mêmes champs (ie s'appuyer sur le compilateur pour les garder cohérents). Il me permet également d'utiliser les DTO dans la partie vue de mon application, mais les convertit en objets domaine pour l'accès aux affaires et aux données – mwjackson

+0

De plus, votre solution ne fonctionne pas car les contacts ICompany sont de type IList , pas IList . Je voudrais le garder comme IContact pour que mon objet DTO n'ait aucune connaissance de l'objet Contact Domain. – mwjackson

+0

désolé fait le changement supprimant l'implémentation de l'interface – alexl

0

Et que dois-je faire si je [hasMany] attribuer? En fait, il n'a pas le nom de propriété 'Type', mais [Property] et [BelongsTo] ont.

MISE À JOUR

La réponse est d'utiliser CollectionType = typeof(YourType)

MISE À JOUR 2

Non, cela ne ne fonctionne pas, cette propriété est définie pour le type de collection càd etc. Essayer pour définir [HasMany (typeof (meType), ...)] mais ne fonctionne toujours pas.

Questions connexes