Skip to content

Rendering without HTTPContext #600

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
RAAAJohnson opened this issue Sep 21, 2018 · 5 comments
Closed

Rendering without HTTPContext #600

RAAAJohnson opened this issue Sep 21, 2018 · 5 comments

Comments

@RAAAJohnson
Copy link

I'm able to generate the HTML from a react component with the following code when processing an Http request. However the initialization blows up when ran elsewhere. Is it possible to render a component to html without an HTTPContext?

var environment = ReactEnvironment.Current; var reactComponent = environment.CreateComponent(component, props); var html = reactComponent.RenderHtml(renderServerOnly: true);

System.NullReferenceException: Object reference not set to an instance of an object.
   at React.AspNet.HttpContextLifetimeProvider.get_Registrations()
   at React.AspNet.HttpContextLifetimeProvider.GetObject()
   at React.TinyIoC.TinyIoCContainer.CustomObjectLifetimeFactory.GetObject(Type requestedType, TinyIoCContainer container, NamedParameterOverloads parameters, ResolveOptions options)
   at React.TinyIoC.TinyIoCContainer.ResolveInternal(TypeRegistration registration, NamedParameterOverloads parameters, ResolveOptions options) 
@Daniel15
Copy link
Member

Daniel15 commented Sep 22, 2018

This is because some classes are registered "per request":

/// Registers a class such that every ASP.NET web request has a single instance of it.
/// </summary>
/// <param name="httpContextAccessor">ASP.NET HTTP context accessor</param>
/// <param name="registerOptions">Registration options</param>
/// <returns>Registration options (for chaining)</returns>
private static TinyIoCContainer.RegisterOptions AsPerRequestSingleton(
IHttpContextAccessor httpContextAccessor,
TinyIoCContainer.RegisterOptions registerOptions
)
{
return TinyIoCContainer.RegisterOptions.ToCustomLifetimeManager(
registerOptions,
new HttpContextLifetimeProvider(httpContextAccessor),
"per request singleton"
);
}

This means there's one singleton instance per request, and that instance is disposed at the end of the request. If there's no current request, this won't work, as we don't know the lifetime that the object should have.

One potential solution I can think of is to update HttpContextLifetimeProvider to handle the case when there's no current request, and just use transient instances (create a new instance on every call) in that case. We'd need to test and ensure there's no memory leaks though.

cc @dustinsoftware - What do you think of this?

@coka
Copy link
Contributor

coka commented Sep 22, 2018

This is like #449, but for .NET Core, right? Maybe there is something similar to HostingEnvironment in the newer framework.

@RAAAJohnson
Copy link
Author

Thanks for the explanation Daniel15. Right coka it does look similar and I am running on .NET Core.

@dustinsoftware
Copy link
Member

One potential solution I can think of is to update HttpContextLifetimeProvider to handle the case when there's no current request, and just use transient instances (create a new instance on every call) in that case. We'd need to test and ensure there's no memory leaks though.

I like this, let's keep this issue open until we add support for this.

@dustinsoftware
Copy link
Member

I'm closing issues for future tasks like this that aren't actively being worked on, but would be open to adding support for this!

#655

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants