ReSharper NHibernate Plugin 1.0 Alpha 1
I’m glad to announce the first alpha release of version 1.0 of my ReSharper NHibernate plugin (v0.9.1). You can download the binary version here. Source code will soon be released.
Please note! The R# open api changes somewhere between build 804 and build 807. The plugin is compiled against build 807 and should work with build 807 and above. Please let me know if you have problems using the plugin with a R# build.
Features for v1.0
Navigation and refactoring
- References to properties and fields in mapping files are found. That means you can Ctrl-Click (Go To Declaration) on a mapped property in the mapping file to navigate to its declaration.
- Full rename refactoring support on mapped properties and fields.
- You can navigate from the declaration to the mapping file by Go To Usage (or Find Usages).
- NHibernates access attribute is interpreted so that mapped fields are found. Note that internal or private fields are not found because of a limitation in ReSharpers reference searcher. If mapping file and implementation of the mapped class are in different assemblies the mapping assembly should reference the assembly with the class implementaion in order to find the references.
Analysis support for .hbm.xml files
- Undefined mapped properties are marked
- Undefined types and namespaces are marked
- Mapping files that are not embedded as resource are marked (#1 error)
- Undefined access attribute values are marked (only the predefined values are supported)
- The severity of the errors can be configured under ReSharper | Options | Code Inspection | Inspection Severity | NHibernate mappings.
What’s next?
The next days I will work on releasing the plugin as open source. Plans for future releases are better support for class names and quick fixes for errors found in code inspection. If you would like to see any feature drop me a note please.
Hope you enjoy it! If you find any bugs it would be nice to hear from you!
Tags: NHibernate, ReSharper
May 26th, 2008 at 20:59
[...] note that there is an update to the [...]
May 26th, 2008 at 21:00
[...] note that there is an update to the [...]
May 26th, 2008 at 21:42
nice to see you’re still working on it, when R# 4.0 is out, I will try it fo sure
yeah, nhib’s xml files are so inspirating, need some clever tool that will do all hard work for me
May 26th, 2008 at 22:33
Any reason to use this over Castle Active Record?
May 27th, 2008 at 8:19
Hi Adam,
if you have a domain model that is infrastructure ignorant you have no other chance than using .hbm.xml mapping files. But of course there are reasons to use active record.
Regards,
Stefan Lieser
May 27th, 2008 at 13:05
Nice idea! Unfortunately I normally map fields instead of properties, so the plugin recognizes none of my mappings
As you said, it’s R#’s fault, though.
I found one issue. Apparently the plugin does not search base classes when looking for property setters. It is valid to define a property with getter + setter in a base class and shadow the property in a derived class (the mapped class) using new. NHibernate will find and use the shadowed version in the base class, your plugin won’t.
Ex:
public class Entity {
public TId ID { get; set; }
}
public class MappedClass : Entity {
public new int ID {
get { return base.ID; }
}
}
May 27th, 2008 at 13:46
@Andre: as a workaround you can declare your fields protected instead of private or internal, than R# will find them.
I asume you’ve mapped class MappedClass and property ID. This works for me (R# 809, plugin 0.9.1). Even if ID is of type int in Entity and of type long in MappedClass. And even if MappedClass doesn’t ‘new’ the property, the getter/setter are found in base class Entity.
So can you mail me a demo project to reproduce the bug to stefan … lieser-online.de?
May 31st, 2008 at 15:50
[...] ReSharper NHibernate Plugin 1.0 Alpha 1 When does design happen in agile? Patterns In Practice: The Open Closed Principle Castle Demo App #3: Saving time and effort with advanced Monorail features [...]
June 2nd, 2008 at 10:13
Hi!
Nice plugin or at least idea. Haven’t been able to test it yet due to this exception thrown when editing all my hbm file. Pasted to example files below. Hope this can be fixed.
Regards
JetBrains.Util.LoggerException: Metoden hittades inte: JetBrains.ReSharper.Psi.IAccessor JetBrains.ReSharper.Psi.IProperty.get_Getter(). —> System.MissingMethodException: Metoden hittades inte: JetBrains.ReSharper.Psi.IAccessor JetBrains.ReSharper.Psi.IProperty.get_Getter().
at NHibernatePlugin.Analysis.MappingFile.MappingFileAnalysisElementProcessor.HighlightProperty(AccessMethod access, String propertyName, IProperty property, IElement nameAttribute, String className)
at NHibernatePlugin.Analysis.MappingFile.MappingFileAnalysisElementProcessor.HighlightUndefinedMappedProperty(IXmlTag xmlTag, String propertyName, IElement nameAttribute, IElement typeAttribute, ITypeElement typeElement, AccessMethod access, String attributeName) in C:\Code\NHibernatePlugin2\NHibernatePlugin\Analysis\MappingFile\MappingFileAnalysisElementProcessor.cs:line 393
at NHibernatePlugin.Analysis.MappingFile.MappingFileAnalysisElementProcessor.HighlightUndefinedProperty(IXmlTag xmlTag, ITypeElement typeElement, String typeAttributeName) in C:\Code\NHibernatePlugin2\NHibernatePlugin\Analysis\MappingFile\MappingFileAnalysisElementProcessor.cs:line 383
at NHibernatePlugin.Analysis.MappingFile.MappingFileAnalysisElementProcessor.ProcessId(ITreeNode tagHeaderNode, ITypeElement typeElement) in C:\Code\NHibernatePlugin2\NHibernatePlugin\Analysis\MappingFile\MappingFileAnalysisElementProcessor.cs:line 214
at NHibernatePlugin.Analysis.MappingFile.MappingFileAnalysisElementProcessor.ProcessClassElement(XmlTag classTag) in C:\Code\NHibernatePlugin2\NHibernatePlugin\Analysis\MappingFile\MappingFileAnalysisElementProcessor.cs:line 89
at NHibernatePlugin.Analysis.MappingFile.MappingFileAnalysisElementProcessor.ProcessBeforeInterior(IElement element) in C:\Code\NHibernatePlugin2\NHibernatePlugin\Analysis\MappingFile\MappingFileAnalysisElementProcessor.cs:line 53
at JetBrains.ReSharper.Psi.ExtensionsAPI.Tree.TreeElement.ProcessDescendants(IRecursiveElementProcessor processor) in c:\Agent\work\637e155a2fcb7d81\src\Psi\src\ExtensionsAPI\Tree\TreeElement.cs:line 72
at JetBrains.ReSharper.Psi.ExtensionsAPI.Tree.TreeElement.ProcessDescendants(IRecursiveElementProcessor processor) in c:\Agent\work\637e155a2fcb7d81\src\Psi\src\ExtensionsAPI\Tree\TreeElement.cs:line 74
at NHibernatePlugin.Analysis.MappingFile.MappingFileAnalysisDaemonStageProcess.Execute() in C:\Code\NHibernatePlugin2\NHibernatePlugin\Analysis\MappingFile\MappingFileAnalysisDaemonStageProcess.cs:line 28
at JetBrains.ReSharper.Daemon.Impl.DaemonProcessBase.DoHighlighting(DaemonProcessKind kind) in c:\Agent\work\637e155a2fcb7d81\src\Daemon\src\Impl\DaemonProcessBase.cs:line 321
— End of inner exception stack trace —
at JetBrains.ReSharper.Daemon.Impl.DaemonProcessBase.DoHighlighting(DaemonProcessKind) in c:\Agent\work\637e155a2fcb7d81\src\Daemon\src\Impl\DaemonProcessBase.cs:line 329 column 19
at JetBrains.ReSharper.Daemon.Impl.VisibleDocumentDaemonProcess.DoHighlighting(Boolean) in c:\Agent\work\637e155a2fcb7d81\src\Daemon\src\Impl\VisibleDocumentDaemonProcess.cs:line 188 column 9
at JetBrains.ReSharper.Daemon.Impl.c__DisplayClass1.b__0() in c:\Agent\work\637e155a2fcb7d81\src\Daemon\src\Impl\VisibleDocumentDaemonProcess.cs:line 174 column 60
at JetBrains.ReSharper.Daemon.Impl.DaemonThread.ThreadProc() in c:\Agent\work\637e155a2fcb7d81\src\Daemon\src\Impl\DaemonThread.cs:line 127 column 13
at System.Threading.ThreadHelper.ThreadStart_Context(Object)
at System.Threading.ExecutionContext.Run(ExecutionContext, ContextCallback, Object)
at System.Threading.ThreadHelper.ThreadStart()
hbm-file:
class:
using System;
using NHibernateTools.DataInterfaces;
namespace Praktikplatsen.Core.Domain
{
///
/// KontaktKopplaPlats object for NHibernate mapped table kontakt_koppla_plats.
///
[Serializable]
public class KontaktKopplaPlats : DomainObject
{
private Int32 _kontaktId;
private Kontakt _kontaktIdKontakt;
private Int32 _platsId;
private ForetagPlats _platsIdForetagPlats;
private DateTime _uppdateradLogg;
public KontaktKopplaPlats()
{
}
public KontaktKopplaPlats(Int32 id)
{
base.ID = id;
}
public virtual Int32 KontaktId
{
get { return _kontaktId; }
set { _kontaktId = value; }
}
public virtual Int32 PlatsId
{
get { return _platsId; }
set { _platsId = value; }
}
public virtual DateTime UppdateradLogg
{
get { return _uppdateradLogg; }
set { _uppdateradLogg = value; }
}
public virtual ForetagPlats ForetagPlats
{
get { return _platsIdForetagPlats; }
set { _platsIdForetagPlats = value; }
}
public virtual Kontakt Kontakt
{
get { return _kontaktIdKontakt; }
set { _kontaktIdKontakt = value; }
}
public override int GetHashCode()
{
return ID.GetHashCode();
}
}
}
June 2nd, 2008 at 11:56
@cws: Please use version 0.9.1 of nhibernate plugin. There was a breaking change in R# open api (Method ‘Getter(boolean)’ was changed to property ‘bool Getter’).
June 3rd, 2008 at 9:58
Hi!
Thanks for replying. I was using 0.9.1 but build 804 of R# 4, but now I have upgraded to the latest build.
The analysis features seems to work but not the navigation and refactoring features. Is there something I have to do to make those features work.
Regards
June 3rd, 2008 at 10:41
@cws: Navigation and refactoring should work out of the box. Can you please verify if R# underlines a mapped property if you hover with the mouse over it while pressing Ctrl?
June 4th, 2008 at 9:47
Hi!
I am using build 815 of R#4 and 0.9.1 of your plugin. I have tested with vs2008 and vs2005 but no diffrence.
When pressing Ctrl the underline goto declatarion don’t show. Find usages dosen’t work as well in the mapping document. I have mailed you a example project, if you won’t to have a look.
Regards
June 4th, 2008 at 16:48
@cws: I use 816 with VS2008 and your solution works just as expected. But I’m using the trunk version of course, so please wait until the next release of NHibernate plugin which should come tomorrow.
Regards,
Stefan
June 13th, 2008 at 22:00
Hello!
Works now with 0.9.2 release.
Very nice!
Regards