Programmation d'interfaces tandis que la cartographie avec NHibernate Fluent
J'ai été fouettée à la soumission et ont commencé à apprendre à parler Couramment NHibernate (pas de précédent NHibernate de l'expérience). Dans mon projet, je suis à la programmation d'interfaces pour réduire le couplage etc. Que signifie à peu près "tout" fait référence à l'interface plutôt que sur le béton type (IMessage au lieu de Message). La pensée derrière c'est pour aider à la rendre plus testable en étant capable de se moquer de dépendances.
Cependant, (Courant) NHibernate n'aime pas quand j'essaie de la carte d'interfaces au lieu de classes concrètes. La question est simple: en fonction de la fluidité de la Wiki, il est intelligent pour définir le champ ID de ma classe comme par exemple
int Id { get; private set; }
pour obtenir un typique auto-généré de clé primaire. Toutefois, cela ne fonctionne qu'avec les classes de béton - je ne peux pas spécifier un niveau d'accès sur une interface, où la même ligne doit être
int Id { get; set; }
et je pense qu'il nie faire le setter privé dans la classe concrète (l'idée que seule la NHibernate devrait jamais de définir l'IDENTIFIANT attribué par l'DB).
Pour l'instant, je pense que je vais juste faire le setter public et éviter la tentation de l'écriture pour elle.. Mais quelqu'un aurait-il une idée de ce que serait le "bon", les meilleures pratiques pour créer un bon de clé primaire domaine que seulement NHibernate peut écrire pour tout encore que la programmation d'interfaces?
Mis à JOUR
De ce que je comprends après les deux réponses ci-dessous à partir de mookid et James Gregory, je peut très bien être sur la mauvaise voie - là ne devrait pas être une raison pour moi d'avoir une interface par entité comme je l'ai maintenant. C'est bien et bon. Je suppose que ma question devient alors - n'est-il pas raison à 100% contre une interface pour toutes les entités? Et si il n'y a même pas une seule situation où il pourrait être justifié, est-il possible de faire cela avec (Courant) NHibernate?
Je demande parce que je ne sais pas, de ne pas être critique. Merci pour les réponses. 🙂
- C'est drôle parce que certains développeurs respect j'ai accidentellement pris sur l'entité de l'interface de l'anti-modèle. C'est plus une erreur que les pros font, que les novices, car les recrues à peine de savoir pourquoi les interfaces sont important en premier lieu.
- Si vous n'êtes pas la création d'interfaces pour vos entités, alors comment voulez-vous tester le comportement de votre entités? Plus précisément, comment vous vous moquez des dépendances de cette entité?
- Quand les gens disent à programmer des interfaces pas implémentations ils ne signifient pas la langue de l'interface de construire. Ils signifient essayer de boîte noire le code que vous utilisez autant que possible. I. e. Lors de l'utilisation d'un agent Recenseur sur un dictionnaire ne présumez pas de Courant ne lèvera pas avant movenext est appelée qu'il n'est pas défini et peut changer.
- J'ai pensé à cette approche moi - même- à l'aide des interfaces pouvait m'apporter une solution facile de la zone de l'abstraction de mes objets de données. Malheureusement, comme vous pouvez accidentellement mis un ID à une mise en œuvre de toute entité de l'interface, vous avez la chose que vous voulez éviter de), vous (ou quelqu'un de consommer votre code) peut accidentellement créer une classe de mise en œuvre de plus d'une entité de l'interface. Je crois que le mettre dans un sacré désordre. Personnellement, je préfère utiliser les classes abstraites à la place.
- si votre entités sont simples POCOs, détaché de l'ORM attributs spécifiques/comportement (c'est à dire à l'aide d'attributs de descripteurs), alors rien ne vous arrête de directement utiliser dans vos scénarios de test. J'ai l'impression que ce n'est plus une pratique moderne de couple à une entité de l'ORM de mise en œuvre. Si, toutefois, vous êtes à l'aide de Microsoft Cadre de l'Entité et l'Entité de base de la classe, par exemple, ou d'avoir "hérité" d'un projet avec déjà couplée à des entités à l'ORM de fonctionnalités spécifiques, compte tenu de l'entité abstraction est raisonnable.
Vous devez vous connecter pour publier un commentaire.
Mise à JOUR: à l'aide de l'union-subclass n'est pas pris en charge via l'interface fluide fluide-nhibernate fournit. Vous aurez à utiliser régulièrement hbm fichier de mappage et l'ajouter.
Moi aussi je suis en train de le faire avec NHibernate fluent. Je ne pense pas que cela devrait être un problème de cartographie des interfaces. Vous souhaitez utiliser une stratégie d'héritage, plus précisément le table par le béton de classe de la stratégie.
Essentiellement, vous créez un mappage de la définition de la classe de base (dans ce cas, votre interface) et de spécifier comment NHibernate doit traiter avec les maîtres d'œuvre en utilisant de l'union-subclass.
Ainsi, par exemple, cela devrait vous permettre de faire des polymorphes associations:
Note de la façon dont l'Id est le même pour tous les bétons, les implémenteurs. NHibernate à ce. Aussi, IAccountManager table n'existe pas réellement.
Vous pouvez aussi essayer de tirer parti de NHibernate Implicite du Polymorphisme (décrite ci-dessous la table par le béton de classe de la stratégie) - mais il a des tonnes de limitations.
Je sais que c'est une diversion, et pas de réponse à votre question (bien que je pense mookid a obtenu que les couverts).
Vous devriez vraiment évaluer si les interfaces sur votre domaine entités sont en fait d'offrir quelque chose de valeur; il est rare de trouver une situation où vous avez réellement besoin pour ce faire.
Par exemple: Comment s'appuyant sur
IMessage
moins couplé que de compter surMessage
, quand ils ont tous les deux (presque) sans aucun doute identique signatures? Vous ne devriez pas avoir besoin de se moquer d'une entité, car il est rare qu'il ait suffisamment de comportement à exiger d'être moqué.Vous pouvez régler votre interface ne contiennent qu'un getter:
Votre classe concrète peut encore mettre en œuvre un setter ainsi, et puisque vous êtes la programmation à votre interface vous permettra de ne jamais appeler le setter "par accident".
Si vous voulez interdire le réglage de l'id de même lorsque vous maintenez une référence à un exemple concret, vous pouvez éviter de mettre en œuvre un setter, puis laissez NHibernate l'accès au lieu de la propriété - c'est vrai, NHibernate pouvez utiliser quelques chouettes réflexion ruse pour définir votre id de domaine directement au lieu d'invoquer la propriété. Alors vous pouvez mapper l'id comme ceci:
dans ce cas, votre
Id
propriété doit être soutenue par un correspondantid
champ. Il y a plus de conventions de nommage, par exemple, si vous préférez souligne que privé champ préfixe.Je rencontre exactement le même problème.
Malheureusement, j'ai une raison valable pour utiliser l'entité interfaces; le modèle d'entité sera mis en œuvre de différentes façons et avec différents mappages par le client.
L'ensemble du modèle doit être en lecture seule, les interfaces sont du style:
Des implémentations concrètes puis de mettre en œuvre ces internes setters:
J'ai descendu la route de la cartographie pour les classes concrètes. Tout est parfait jusqu'à ce que vous créer des relations qui le retour des interfaces et doivent être exprimées pour des implémentations concrètes.
peut devenir
Mais il n'y a pas d'équivalent "cast" pour
De cartographie des interfaces (le plus propre solution) lance le problème mentionné ci-dessus en ce que la pièce d'identité doit exister sur la plus haute classe pour l'établissement et nécessite un setter sur l'interface.
Pour l'instant, ma seule solution est d'ajouter des organismes de normalisation pour tous les Id d'interface des champs. Ses une honte de l'Id ne peut pas exister à l'intérieur d'une sous-classe ou d'avoir son type de fonte à partir de l'interface.
References(x => x.House).Class<House>();
?Ressemble, je n'ai pas assez de réputation pour des commentaires sur d'autres peuples encore les réponses, je vais faire une réponse dans son propre droit.
Références a maintenant une surcharge générique pour permettre la fonte qui theGecko cherchais dans ses réponses.