2013-10-11 28 views
0

我已将一个新的WebApi项目添加到我的解决方案中,并且Controllers Get Method调用了一个返回Xml的函数。我正在调用一个使用Nhibernate ISession实例化的函数。我的Db使用MySql我得到以下错误。将Web Api Nhibernate会话传递给控制器​​

以下是错误的痕迹

<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文件调用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. 
     } 

    } 

通常有实例化一次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会话仍然为空。

回答

0

这听起来像你在“会话”一词有些迷茫......

MVC通常具有一旦控制器被击中

的NHibernate的会议是不一样的实例化的会话作为ASP.NET(MVC)会话。您使用ISessionFactory.OpenSession()创建NHibernate会话。有关如何获得NHibernate会话的更详细说明,请参阅chapter 3 of the documentation

+0

谢谢丹尼尔。我想我在这里误导你们。我实际上是指ISessionfactory的会话。我知道,在我们的普通Web项目中,由于Global.asax中的逻辑,当应用程序启动时,此会话已经实例化,但对于Webapi,当我使用相同的逻辑和web.config时,它不起作用。我希望我澄清了我的问题。提前致谢。 –

+0

我无法找到为什么解决依赖关系的原因,但我解决了这个问题,并使用了一个普通控制器来返回一个XML。我读过的大部分博客都询问了注册APIControllers。 –