Esse artigo é um update do artigo 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 “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 artigo foi escrito e que eu testei, ela é do dia 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 artigo 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. Para 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úvidas essa ausência é problemática para o .NET Core, e está prestes a ser resolvida.
***
Este artigo foi produzido em parceria com a Lambda3. Leia outros conteúdos no blog da empresa: blog.lambda3.com.br