我在我的解决方案中添加了一个新的 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 仍然为空。