I have added a new WebApi project to my solution and Controllers Get Method calls a function which returns an Xml . Am calling an function which uses a Nhibernate ISession to instantiate . Am using MySql for my Db I get the following error.
Here is a trace of the error
<Error>
<Message>An error has occurred.</Message>
<ExceptionMessage>
Object reference not set to an instance of an object.
</ExceptionMessage>
<ExceptionType>System.NullReferenceException</ExceptionType>
<StackTrace>
at comp.rest.RestApi.Controllers.RestApiController.Get() in C:\GitHub\rea-rest\src\comp.rest.RestApi\Controllers\RestApiController.cs:line 23 at lambda_method(Closure , Object , Object[] ) at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<>c__DisplayClass13.<GetExecutor>b__c(Object instance, Object[] methodParameters) at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.Execute(Object instance, Object[] arguments) at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.<>c__DisplayClass5.<ExecuteAsync>b__4() at System.Threading.Tasks.TaskHelpers.RunSynchronously[TResult](Func`1 func, CancellationToken cancellationToken)
</StackTrace>
</Error>
I do have a dependency resolver which i call from the global.asax file on app start
public class ApiDependencyResolver : IDependencyResolver
{
private static ISession _session;
private static ISettings _settings;
private static IDiscountService _discountService;
private static IAuctionService _auctionService;
private static IAuditService _auditService;
private NhProductAdminService productAdminService = new NhProductAdminService(_session, _settings,
_discountService,
_auctionService,
_auditService);
public IDependencyScope BeginScope()
{
// This example does not support child scopes, so we simply return 'this'.
return this;
}
public object GetService(Type serviceType)
{
if (serviceType == typeof(RestApiController))
{
return new RestApiController(productAdminService);
}
else
{
return null;
}
}
public IEnumerable<object> GetServices(Type serviceType)
{
return new List<object>();
}
public void Dispose()
{
// When BeginScope returns 'this', the Dispose method must be a no-op.
}
}
Usually has the Nhibernate session instantiated once the controller is hit this is because we have already opened a session in the global.asax Application_Start, I am stuck at this for a few days now , Would be great for anyone to help me out , Am sure am doing something silly . Am new to WebApi .
In our Web Application we Open the Nhibernate Session using the global.asax .
builder.RegisterModule(new WebNHibernateModule());
var container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
The WebHibernate Class looks like this
public class WebNHibernateModule : NHibernateModule
{
protected override IPersistenceConfigurer DatabaseConfig
{
get
{
return
MySQLConfiguration.Standard
.ConnectionString(s => s.FromConnectionStringWithKey("ApplicationServices"))
.Driver<ProfiledSqlClientDriver>();
//.ShowSql();
}
}
protected override Action<MappingConfiguration> MappingConfig
{
get { return AutoConfig.Mappings; }
}
}
public class ProfiledSqlClientDriver : MySqlDataDriver
{
public override IDbCommand CreateCommand()
{
var command = base.CreateCommand();
if (MiniProfiler.Current != null)
{
command = DbCommandProxy.CreateProxy(command);
}
return command;
}
}
The NHibernateModule Class looks like this
public abstract class NHibernateModule : Module
{
protected abstract IPersistenceConfigurer DatabaseConfig { get; }
protected abstract Action<MappingConfiguration> MappingConfig { get; }
protected override void Load(ContainerBuilder builder)
{
builder.RegisterGeneric(typeof(NhSessionQueryable<>)).As(typeof(IQueryable<>));
builder.RegisterType<NhQueryContext>().As<IQueryContext>();
builder.RegisterType<WebSessionTracker>().As<ISessionTracker>()
.InstancePerHttpRequest();
builder.Register(c => c.Resolve<ISessionFactory>().OpenSession())
.InstancePerHttpRequest()
.OnActivated(e =>
{
e.Context.Resolve<ISessionTracker>().CurrentSession = e.Instance;
e.Instance.BeginTransaction();
});
builder.Register(c =>
Fluently.Configure().Database(DatabaseConfig)
.Mappings(MappingConfig)
.BuildConfiguration())
.SingleInstance()
.OnActivated(e =>
{
e.Instance.Initialize(e.Context.Resolve<ValidatorEngine>());
new SchemaValidator(e.Instance).Validate(); // Validate the schema when we create the session factory
});
builder.Register(c => c.Resolve<Configuration>().BuildSessionFactory())
.SingleInstance();
}
}
Usually in our Web Application similar Autofac is used to prepopulate the session , Am doing the same for the WebApi as well , but the Nhibernate Session is still null .