SQLite NHibernate configuration with .Net 4.0 and vs 2010 - nhibernate

I am updating this post with what I think I now know about getting this configuration; HOWEVER, there is more to know as I am still having a problem is one crucial area.
I use SQLite for unit testing, which now works fine, using the configuration steps below. I also use it when I want a test run of the UI with more data than in-memory test data but without the overhead of SQLServer - this configuration fails with the following:
{"Could not create the driver from NHibernate.Driver.SQLite20Driver, NHibernate, Version=2.1.0.4000, Culture=neutral, PublicKeyToken=aa95f207798dfdb4."}
Here is updated info on configs that DO work:
1) Which SQLite dll?? There are some bad links out there that look helpful but that have build errors in them. The only good download as of this date is here at Source Forge. v1.066 which was released today, 4-18-2010.
2) Must you use the GAC? No, as answered by Mauricio.
3) x64 builds - as answered by Mauricio.
4) NHib driver - SQLite20Driver, as answered by Mauricio
5) FNH as a potential conflict - no, as answered by Mauricio
Cheers,
Berryl
== ADD'L DEBUG INFO ===
When the exception is hit and I call up the SQLite20Drive assembly, I get the following which suggests to me that the driver should be available. I am wondering though, as the configuration code is in a different assembly.
-- assembly when error ----
?typeof(SQLite20Driver).Assembly
{NHibernate, Version=2.1.0.4000, Culture=neutral, PublicKeyToken=aa95f207798dfdb4}
[System.Reflection.RuntimeAssembly]: {NHibernate, Version=2.1.0.4000, Culture=neutral, PublicKeyToken=aa95f207798dfdb4}
CodeBase: "file:///C:/Users/Lord & Master/Documents/Projects/Smack/trunk/src/ConstructionAdmin.WpfPresentation/bin/Debug/NHibernate.DLL"
EntryPoint: null
EscapedCodeBase: "file:///C:/Users/Lord%20%26%20Master/Documents/Projects/Smack/trunk/src/ConstructionAdmin.WpfPresentation/bin/Debug/NHibernate.DLL"
Evidence: {System.Security.Policy.Evidence}
FullName: "NHibernate, Version=2.1.0.4000, Culture=neutral, PublicKeyToken=aa95f207798dfdb4"
GlobalAssemblyCache: false
HostContext: 0
ImageRuntimeVersion: "v2.0.50727"
IsDynamic: false
IsFullyTrusted: true
Location: "C:\\Users\\Lord & Master\\Documents\\Projects\\Smack\\trunk\\src\\ConstructionAdmin.WpfPresentation\\bin\\Debug\\NHibernate.dll"
ManifestModule: {NHibernate.dll}
PermissionSet: {<PermissionSet class="System.Security.PermissionSet"
version="1"
Unrestricted="true"/>
}
ReflectionOnly: false
SecurityRuleSet: Level1
--- assembly when unit testing (NO ERROR)
{NHibernate, Version=2.1.0.4000, Culture=neutral, PublicKeyToken=aa95f207798dfdb4}
[System.Reflection.RuntimeAssembly]: {NHibernate, Version=2.1.0.4000, Culture=neutral, PublicKeyToken=aa95f207798dfdb4}
CodeBase: "file:///C:/Users/Lord & Master/Documents/Projects/Smack/trunk/src/ConstructionAdmin.Tests/bin/Debug/NHibernate.DLL"
EntryPoint: null
EscapedCodeBase: "file:///C:/Users/Lord%20%26%20Master/Documents/Projects/Smack/trunk/src/ConstructionAdmin.Tests/bin/Debug/NHibernate.DLL"
Evidence: {System.Security.Policy.Evidence}
FullName: "NHibernate, Version=2.1.0.4000, Culture=neutral, PublicKeyToken=aa95f207798dfdb4"
GlobalAssemblyCache: false
HostContext: 0
ImageRuntimeVersion: "v2.0.50727"
IsDynamic: false
IsFullyTrusted: true
Location: "C:\\Users\\Lord & Master\\Documents\\Projects\\Smack\\trunk\\src\\ConstructionAdmin.Tests\\bin\\Debug\\NHibernate.dll"
ManifestModule: {NHibernate.dll}
PermissionSet: {<PermissionSet class="System.Security.PermissionSet"
version="1"
Unrestricted="true"/>
}
ReflectionOnly: false
SecurityRuleSet: Level1
Here is the bootstrapper for this a SQLite session:
/// <summary>SQLite-NHibernate bootstrapper for general use.</summary>
public class SQLiteBoot : IDisposable
{
public readonly ISessionFactory SessionFactory;
private readonly ISession _session;
private static Configuration _config;
private static string _persistenceModelGeneratorName;
public SQLiteBoot(IAutoPersistenceModelGenerator persistenceModelGenerator) {
if (_isSessionFactoryBuildRequired(persistenceModelGenerator)) {
_config = new Configuration()
.SetProperty(ENV.ReleaseConnections, "on_close")
.SetProperty(ENV.Dialect, typeof (SQLiteDialect).AssemblyQualifiedName)
.SetProperty(ENV.ConnectionDriver, typeof (SQLite20Driver).AssemblyQualifiedName)
.SetProperty(ENV.ConnectionString, "data source=:memory:")
.SetProperty(ENV.ProxyFactoryFactoryClass, typeof (ProxyFactoryFactory).AssemblyQualifiedName)
.SetProperty(ENV.CurrentSessionContextClass, typeof (ThreadStaticSessionContext).AssemblyQualifiedName);
_persistenceModelGeneratorName = persistenceModelGenerator.Name;
var persistenceModel = persistenceModelGenerator.Generate();
var fluentCfg = Fluently.Configure(_config).Mappings(m => m.AutoMappings.Add(persistenceModel));
SessionFactory = fluentCfg.BuildSessionFactory();
Check.Require(SessionFactory.GetAllClassMetadata().Count > 0, "No mapped classes - check your AutoPersistenceModel!");
}
_session = SessionFactory.OpenSession();
CurrentSessionContext.Bind(_session);
new SchemaExport(_config).Execute(true, true, false, _session.Connection, Console.Out);
}
private bool _isSessionFactoryBuildRequired(IAutoPersistenceModelGenerator persistenceModelGenerator)
{
return
_config == null
|| SessionFactory == null
|| !persistenceModelGenerator.Name.Equals(_persistenceModelGeneratorName);
}
public void Dispose()
{
_session.Dispose();
}
}
}

Sure. You can also use previous versions if you configure mixed mode loading.
No need to be in the GAC. You can use gacutil to remove the assemblies from the GAC.
Use the x64 DLL to target Windows x64 and x86 for Windows x86
Please post the full exception stack trace. Also if you're using a 3.5 assembly use mixed mode loading.
FNH has no reference to SQLite.

I want this to stand out so it will help someone else; the full reason this happens is explained here; so adjust your congig to use BOTH the redirect there in combo with the mixed loading mode referenced here by Mauricio.

I had the same problem, and found little or no help on all the forum and blog posts.
Note that this problem is specific to a case respecting all of the following criteria:
- using SQLite
- with System.Data.SqlLite
- on an x64 machine
- and NHibernate (2.1.2.4 in my case)
That chunk of config in my web.config (or app.config for my unit tests) got it to work. I had to qualify the assembly to be sure he loads correctly.
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<qualifyAssembly
partialName="System.Data.SQLite"
fullName="System.Data.SQLite, Version=1.0.66.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=AMD64" />
</assemblyBinding>
</runtime>
</configuration>
Somewhere in it's inner plumbing, during the mapping using scanned assemblies, NHibernate creates an Assembly object using it's paritla name, as a string, "System.Data.SQLite". Somehow, the x86 version of the assembly got loaded.
The above configuration made sure that using the partial name to load an assembly would provide the x64 version.
EDIT: I use version 1.0.66.0 and took the DLL under the bin\x64 folder in the file SQLite-1.0.66.0-binaries.zip available on sourceforge here.

Related

Assembly 'System.Web.Http, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' uses 'System.Net.Http.Formatting, Version=5.2.3.0

I m getting the below error message while running the WebAPI service.
'System.Web.Http, Version=5.2.2.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The
located assembly's manifest definition does not match the assembly
reference. (Exception from HRESULT: 0x80131040)
Here are the version information
System.Web.Http 5.2.3
System.Web.Http.OData 5.5
System.Web.Http.WebHost 5.2.3
NewtonSoft.Json 6.0
Copy to Local set to True for all the Dll's. I tried to do update -package using Nuget and no go.
If i remove the OData reference, its working fine.
I tried it in the other way by adding OData reference and including the namespace and simply commented the method where i used ODataQueryOptions, then it worked fine. Please help me with this and if any further information is required, i m happy to add it as well
[HttpGet]
public HttpResponseMessage GetEventStatusTypes (ODataQueryOptions<UnAuthEventStatusType> options)
{
try
{
using (UnAuthAppAdminBusLib unAuthAppAdminBusLib = new UnAuthAppAdminBusLib())
{
var eventStatusTypes = unAuthAppAdminBusLib.GetEventStatusType(options) as IEnumerable<UnAuthEventStatusType>;
return Request.CreateResponse<IEnumerable<UnAuthEventStatusType>> (HttpStatusCode.OK, eventStatusTypes);
}
}
catch (Exception ex)
{
return Request.CreateResponse<string>(HttpStatusCode.InternalServerError, ex.Message);
}
}

SignalR 2.0 error /signalr/hubs 404 (Not Found) when using IIS

I'm having some issues with SignalR 2.0 in EPiServer 7.5 (a MVC4 framework). All I get is a 404 error
GET http://web.com/signalr/hubs 404 (Not Found)
I'm hosting everything on a Windows 2012 R2 Server. Also noteworthy is that the solution works when running everything in IIS Express from Visual Studio but not in IIS 8.5.
What I've done so far is to add the SingalR references.
Microsoft.AspNet.SignalR.Client, 2.0.0.0
Microsoft.AspNet.SignalR.Core, 2.0.0.0
Microsoft.AspNet.SignalR.System.Web, 2.0.0.0
Microsoft.OWin, 2.1.0.0
Microsoft.OWin.Host.SystemWeb, 2.1.0.0
Microsoft.Owin.Security, 2.0.0.0
Owin, 1.0.0.0
Startup.cs
The startup is intitialized on application start so that seems to work.
[assembly: OwinStartup(typeof(Web.Startup))]
namespace Web
{
public class Startup
{
#region Local variables
private static readonly ILog Logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
#endregion
#region Methods
/// <summary>
/// Configure SignalR
/// </summary>
/// <param name="app"></param>
public void Configuration(IAppBuilder app)
{
try
{
Logger.MethodCallEntry();
// Any connection or hub wire up and configuration should go here
//app.MapSignalR(); // Doesn't work either
var hubConfiguration = new HubConfiguration
{
EnableDetailedErrors = true,
EnableJavaScriptProxies = false
};
app.MapSignalR("/signalr", hubConfiguration);
}
catch (Exception ex)
{
Logger.Error("Failed to initialize or map SignalR", ex);
}
finally
{
Logger.MethodCallExit();
}
}
#endregion
}
}
Script inclusion
<script src="/Static/Frameworks/Scripts/jquery-1.10.2.js"></script>
<script src="/Static/Frameworks/Scripts/knockout-3.0.0.js"></script>
<script src="/Static/Frameworks/Scripts/modernizr.2.7.0.js"></script>
<script src="/Static/Frameworks/Scripts/jquery.signalR-2.0.1.js"></script>
<!-- also tried path ~/signalr/hubs -->
<script src="/signalr/hubs"></script>
This is not a solution updated from 1.x SignalR!
just wanted to put my 2 cents in. I had this error, and it ended up being because i had
<add key="owin:AutomaticAppStartup" value="false" />
in my web.config. removing this line fixed everything up for me!
The error was the exact same as in this post
http://blogs.msdn.com/b/praburaj/archive/2013/12/02/owin-startup-class-not-detected.aspx
The solution was to totally empty the asp.net cache
Run this in PowerShell
net stop w3svc
Remove-Item -Path "C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\root\*" -Force -Recurse
Remove-Item -Path "C:\Windows\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files\root\*" -Force -Recurse
net start w3svc
I just had a similar problem getting the "MoveShape" demo to work on a freshly built Win 2012R2 server. I resolved the problem by adding the role/features: "Web Server (IIS)" -> "Application Development" and selecting ".NET Extensibility 4.5", "ASP.NET 4.5", "ISAPI Extensions", "ISAPI Filters" and "WebSocket Protocol".
Once I restarted the system or IIS, the demo starting working.
My problem was resolved by removing nuget-package "Microsoft.Owin.Host.SystemWeb", which was referenced in packages.config with version="2.1.0" and installing version="3.0.1".
With this version the owin environment was never started on the iis8 on server 2012r2 with the error, that the namespace "Host" was not found.
Microsoft.Common.CurrentVersion.targets(1697,5): warning MSB3245: Could not resolve this reference. Could not locate the assembly "Microsoft.Owin.Host.SystemWeb, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL". Check to make sure the assembly exists on disk.
Startup.cs(2,22): error CS0234: The type or namespace name 'Host' does not exist in the namespace 'Microsoft.Owin' (are you missing an assembly reference?) [*.csproj]
Just had the same 404 problem. Ended up I updated all the DLLs except for one which was problem. I didn't update Microsoft.AspNet.SignalR.SystemWeb.dll

Assembly.LoadFrom(assemblypath) in WCF Servicefactory

I am using a WCF ServicehostFactory for my wcf service in conjunction with unity for service and repository/DAL instantiation using interfaces.
I want to load an assembly into my appdomain (before the service is instantiated), whose types are registered in my web.config for Unity DI.
<assembly name="Customer.DAL.AdventureWorks"/>
<assembly name="Customer.DAL.Blogger"/>
<assembly name="Customer.Interfaces"/>
<assembly name="Customer.DAL"/>
<namespace name="Customer.Interfaces.Repository"/>
<namespace name="Customer.DAL.AdventureWorks"/>
<namespace name="Customer.DAL.Blogger"/>
<container>
<register type="Customer.Interfaces.DAL.IDal, Customer.Interfaces" mapTo="Customer.DAL.API, Customer.DAL">
<lifetime type="transient"/>
</register>
<register type="Customer.Interfaces.Repository.IRepositoryDepartment, Customer.Interfaces" mapTo="Customer.DAL.AdventureWorks.RepositoryDepartment, Customer.DAL.AdventureWorks">
<lifetime type="transient"/>
</register>
<register type="Customer.Interfaces.Repository.IRepositoryBlogs, Customer.Interfaces" mapTo="Customer.DAL.Blogger.RepositoryBlogs, Customer.DAL.Blogger">
<lifetime type="transient"/>
</register>
</container>
and I am using the following code to load the assembly:
Assembly.LoadFile("C:\xxxxx\Customer.DAL.dll"); // loaded from somewhere on disk.
I have verified the existence of the loaded assembly against the current appdomain and the assembly is loaded successfully.
Immediately after that, I try to register the service type using unity, but I get the following exception:
The type name or alias Customer.DAL.API, Customer.DAL could not be resolved. Please check your configuration file and verify this type name.
So why can the type "Customer.DAL.API" not be resolved?
EDIT: I run FusionLog in parallel and it traces out the failed assembly binding.
Why does it actually search for the assembly, cause the this assembly has already been loaded by me using reflection as mentioned above?!
EDIT-II:
#Tuzo:
I read all the articles you posted.
And tried the following:
static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
AssemblyName asname = AssemblyName.GetAssemblyName(#"C:\xxxx\KM_Solution\Customer.DAL\bin\Debug\Customer.DAL.dll");
return Assembly.Load(asname);
}
But I still get the exception. I checked AppDomain.CurrentDomain.GetAssemblies() and I can find my assembly, but it still throws the exception that Unity cannot resolve the type...
I would handle the AssemblyResolve event and load the assembly if you need to:
AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
IUnityContainer container = new UnityContainer()
.LoadConfiguration();
// Example of resolving without hard reference
var customerDal = container.Resolve(
Type.GetType("Customer.Interfaces.Repository.IRepositoryDepartment, Customer.Interfaces"));
private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
string assemblyName = #"C:\xxxxx\" + args.Name + ".dll";
if (File.Exists(assemblyName))
{
return Assembly.LoadFile(assemblyName);
}
return null;
}
In terms of why LoadFile doesn't work, the reason is the Load Context. There are 3 contexts: Load, LoadFrom, and Neither. When you use LoadFile or Load(byte[]) then the assembly is loaded into the Neither context. In the neither context nothing can bind to the assembly without using AssemblyResolve.
See:
Understanding The CLR Binder
Best Practices for Assembly Loading
Suzanne Cook's Blog: Choosing a Binding Context and LoadFile vs. LoadFrom

autofac - dependency injection into IHttpModule

New MVC 4 web application using autofac 3.0 on IIS 7.5. How do I inject a dependency into an IHttpModule?
I tried constructor injection which resulted in:
Constructor on type 'AnonymousIdentityModule' not found
So it seems the internals require a parameterless constructor for http modules. I also tried property injection too but that resulted in no dependency actually being injected.
Registration
builder.RegisterType<AnonymousIdentityModule>().As<IHttpModule>().PropertiesAutowired().InstancePerHttpRequest();
IHttpModule Code
public class AnonymousIdentityModule : IHttpModule
{
private readonly IServiceManager _serviceManager;
// this causes "constructor not found" exception
public AnonymousIdentityModule(IServiceManager serviceManager)
{
_serviceManager = serviceManager;
}
// never assigned by autofac
public IServiceManager ServiceManager
{
get { return _serviceManager; }
set { _serviceManager = value; }
}
...
}
web.config
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<modules>
<add name="AnonymousIdentityModule" type="AnonymousIdentityModule" />
</modules>
</system.webServer>
I found this old article related to Windsor but did not see an equivalent in autofac.
Check out this SO question: IoC Dependency injection into Custom HTTP Module - how? (ASP.NET)
and this post by Phil Haack: http://haacked.com/archive/2011/06/02/dependency-injection-with-asp-net-httpmodules.aspx
They both talk about providing DI to HttpModules by creating another HttpModule to initialize them. And PH has provided a nuget package of his HttpModuleMagic if you want it:
PM> Install-Package HttpModuleMagic
But because HttpModules are only created once they are a kind of singleton, and your dependency also has to be a singleton (or rather, a single instance).
So, if you need a per-request dependency, check out this post: http://blog.sapiensworks.com/post/2013/03/18/Http-Module-Dependecy-Injection-with-Autofac-Gotcha.aspx
This looks at using a Factory function to retrieve a properly scoped dependency when needed.

The 'DbProviderFactories' section can only appear once per config file

We are receiving this error when calling a WCF .net 4.0 service using entity framework.
The 'DbProviderFactories' section can only appear once per config file
It is the first app on the server using EF and other .net 4.0 WCF services are not receiving this error.
Is there any way to correct this error with out editing the machine config file on the server?
The installation for IBM DB2 .NET provider, causes an empty DbProviderFactories, see below. Just delete the second empty entry DbProviderFactories
<system.data>
<DbProviderFactories>
<add name="IBM DB2 for i .NET Provider" invariant="IBM.Data.DB2.iSeries" description=".NET Framework Data Provider for IBM i" type="IBM.Data.DB2.iSeries.iDB2Factory, IBM.Data.DB2.iSeries, Version=12.0.0.0, Culture=neutral, PublicKeyToken=9cdb2ebfb1f93a26" />
</DbProviderFactories>
<DbProviderFactories />
</system.data>
Maybe you could create web.config entries which override any machine-wide settings you want changed.
Described here:
Override machine.config by web.config
Putting the <clear /> instruction inside of the DbProviderFactories tags in the web config to clear out and then override the duplicate entries made in the machine config. Thus doing a hack-work around of the error in the machine.config.
You have to update Machine.config file located in the below paths.
C:\Windows\Microsoft.NET\Framework\v2.0.50727\CONFIG\Machine.Config
C:\Windows\Microsoft.NET\Framework\v4.0.30319\Config\Machine.Config
For 64-bit machines, Machine.config will be located in ...\Framework64\...
The block to pay attention to is this:
<system.data>
<DbProviderFactories>
<add name="IBM DB2 for i5/OS .NET Provider" invariant="IBM.Data.DB2.iSeries" description=".NET Framework Data Provider for i5/OS" type="IBM.Data.DB2.iSeries.iDB2Factory, IBM.Data.DB2.iSeries, Version=12.0.0.0, Culture=neutral, PublicKeyToken=9cdb2ebfb1f93a26"/>
<add name="Microsoft SQL Server Compact Data Provider" invariant="System.Data.SqlServerCe.3.5" description=".NET Framework Data Provider for Microsoft SQL Server Compact" type="System.Data.SqlServerCe.SqlCeProviderFactory, System.Data.SqlServerCe, Version=3.5.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91"/>
</DbProviderFactories>
<!-- This is the line to remove - empty element --><DbProviderFactories/>
</system.data>
As #yonsk already mentioned why this problem occurs (duplicate entry of ), you can create a console application which can fix the machine.config file and then, invoke that console application from your Application's Installer or from your Application whenever you get the Exception. The following code can be used for the console application that will fix the machine.config file.
class Program
{
static void Main()
{
string machineConfigFilePath = RuntimeEnvironment.SystemConfigurationFile;
XDocument xdoc = XDocument.Load(machineConfigFilePath);
XElement[] elements = xdoc.XPathSelectElements("//configuration/system.data/DbProviderFactories").ToArray();
if (elements.Any())
{
foreach (XElement anElement in elements)
{
if (!anElement.HasElements)
anElement.Remove();
}
}
xdoc.Save(machineConfigFilePath);
}
}
If you want to call the console application, from your Application, you would need to invoke that as Administrator. So, the following snippet may help to invoke that console application as Administrator (The user will be prompted with a dialog to accept..)
try
{
Process process = Process.Start(new ProcessStartInfo
{
Verb = "runas",
FileName = "/Path/to/the/console/application",
UseShellExecute = true,
CreateNoWindow = true,
});
process.WaitForExit();
int exitCode = process.ExitCode;
}
catch (Exception ex)
{
}