Esse post é um update do post do Victor Cavalcante do final do ano passado, onde ele analisava um pull request pendente do NHibernate que traria suporte ao .NET Standard para o NH.

Aquele PR ainda está ativo e não foi integrado até hoje. Por outro lado, outro PR acabou entrando, o #1523. Ele é menos ambicioso que o anterior, mas acabou por resolver. O release ainda está pendente por algumas dependências, mas pode acontecer a qualquer momento.

Eu testei rapidamente a implementação e funcionou perfeitamente. Diferentemente do caso do PR testado pelo Victor, neste caso não havia um pacote no Nuget, tive que baixar diretamente a dll do NHibernate.

Outra diferença é que o trabalho de separar os drivers, que estava integrado no PR anterior, ainda não entrou, então não vai aparecer neste exemplo (veja no exemplo do Victor o uso do NHibernate.Driver.SqlServer).

Testando a versão atualizada na branch principal

Para testar, vá até os commits do NHibernate na branch master e clique no check verde, e escolha os detalhes do segundo item, chamado de “NHibernate (Release Package) (NHibernate)”. Você vai cair em uma tela do Team City, e pode logar usando o login anônimo. Clique na aba “Artifacts” e baixe a dll de NHibernate-5.0.3/nuget_gallery/NHibernate-5.0.3.nupkg/lib/netstandard2.0/NHibernate.dll. Lá também tem o xml dos docs.

Se quiser baixar a última compilada quando este post foi escrito e que eu testei, ela é de 5 de Março, e está aqui:

Para testar, crie um projeto .NET Core 2.0 e adicione as seguintes referências:

  • Antlr3.Runtime
  • Iesi.Collections
  • Remotion.Linq
  • Remotion.Linq.EagerFetching
  • System.Configuration.ConfigurationManager
  • System.Data.SqlClient
  • System.Security.Permissions

Todos esses pacotes suportam .NET Standard.

As recomendações do post anterior do Victor sobre os arquivos hbm e xml também valem.

O arquivo final de projeto (csproj) ficará assim:

<Project Sdk="Microsoft.NET.Sdk">
 <PropertyGroup>
 <OutputType>Exe</OutputType>
 <TargetFramework>netcoreapp2.0</TargetFramework>
 </PropertyGroup>
 <ItemGroup>
 <EmbeddedResource Include="Mapping.hbm.xml" />
 <None Update="hibernate.cfg.xml">
 <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
 </None>
 </ItemGroup>
 <ItemGroup>
 <PackageReference Include="Antlr3.Runtime" Version="3.5.1" />
 <PackageReference Include="Iesi.Collections" Version="4.0.4" />
 <PackageReference Include="Remotion.Linq" Version="2.2.0" />
 <PackageReference Include="Remotion.Linq.EagerFetching" Version="2.1.0" />
 <PackageReference Include="System.Configuration.ConfigurationManager" Version="4.4.1" />
 <PackageReference Include="System.Data.SqlClient" Version="4.4.2" />
 <PackageReference Include="System.Security.Permissions" Version="4.4.1" />
 </ItemGroup>
 <ItemGroup>
 <Reference Include="NHibernate">
 <HintPath>/caminho/para/o/NHibernate.dll</HintPath>
 </Reference>
 </ItemGroup>
</Project>

Com isso já é possível rodar o projeto. Dê uma olhada nos arquivos que o Victor recomenda, eles rodaram sem alterações.

Testei o projeto no Windows com Localdb, e também no Linux, com Sql Server também no Linux, e funcionou perfeitamente. Pra fazer isso altere a string de conexão no arquivo hibernate.cfg.xml. O resto fica exatamente igual.

O projeto está no meu Github, em giggio/exemplonhdnetstandard2.

Conclusão

Acredito que em algumas semanas (meses no pior cenário) o NH estará pronto para rodar no .NET Standard (e portanto no .NET Core). O interessante é que temos utilizado o Entity Framework este tempo todo com o .NET Core, por ser o único ORM decente até o momento (outros como Dapper tem propostas diferentes). Ao longo deste período, o EF teve todo o espaço para ganhar este mercado, já que estava isolado do seu principal concorrente, o NH. Essa vantagem está prestes a terminar, e o EF até hoje não tem suporte a funcionalidades fundamentais que se esperam de um ORM, como lazy loading (prevista de forma bastante básica para a versão 2.1, que deve ser lançada este ano). Apesar do endosso da Microsoft, acredito que o NH acabará ganhando a liderança no .NET Core, assim como aconteceu por tantos anos no .NET Framework.

Por outro lado, o .NET Core se fortalece bastante com um ORM mais completo. Sem dúvida essa ausência é problemática para o .NET Core, e está prestes a ser resolvida.

Giovanni Bassi

Arquiteto e desenvolvedor, agilista, escalador, provocador. É fundador e CSA da Lambda3. Programa porque gosta. Acredita que pessoas autogerenciadas funcionam melhor e por acreditar que heterarquia é mais eficiente que hierarquia. Foi reconhecido Microsoft MVP há mais de dez anos, dos mais de vinte que atua no mercado. Já palestrou sobre .NET, Rust, microsserviços, JavaScript, TypeScript, Ruby, Node.js, Frontend e Backend, Agile, etc, no Brasil, e no exterior. Liderou grupos de usuários em assuntos como arquitetura de software, Docker, e .NET.