0

我在我的解决方案中添加了一个新的 WebApi 项目,并且 Controllers Get Method 调用了一个返回 Xml 的函数。我正在调用一个使用 Nhibernate ISession 实例化的函数。我正在为我的 Db 使用 MySql 我收到以下错误。

这是错误的痕迹

<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>

我确实有一个依赖解析器,我在应用启动时从 global.asax 文件中调用它

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.
        }

    }

一旦控制器被击中,通常会实例化 Nhibernate 会话这是因为我们已经在 global.asax Application_Start 中打开了一个会话,我现在被困在这几天了,任何人都可以帮助我,我确定我在做一些傻事。我是 WebApi 的新手。

在我们的 Web 应用程序中,我们使用 global.asax 打开 Nhibernate 会话。

builder.RegisterModule(new WebNHibernateModule());
var container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));

WebHibernate 类看起来像这样

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;
        }
    }

NHibernateModule 类看起来像这样

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();
        }
    }

通常在我们的 Web 应用程序中,类似的 Autofac 用于预填充会话,我也对 WebApi 做同样的事情,但 Nhibernate Session 仍然为空。

4

1 回答 1

0

听起来您对“会话”一词有些困惑...

一旦控制器被击中,MVC 通常会实例化会话

NHibernate 会话与 ASP.NET (MVC) 会话不同。您使用 . 创建一个 NHibernate 会话ISessionFactory.OpenSession()。有关如何获取 NHibernate 会话的更详细说明,请参阅文档的第 3 章。

于 2013-10-11T20:24:03.663 回答