简体   繁体   中英

Passing Web Api Nhibernate Session to Controller

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 .

It sounds like you have some confusion over the term "session"...

MVC usually has the session instantiated once the controller is hit

An NHibernate session is not the same thing as ASP.NET (MVC) session. You create an NHibernate session with ISessionFactory.OpenSession() . See chapter 3 of the documentation for a more detailed explanation of how to get an NHibernate session.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM