Support custom hosting a hybrid between app and component · Issue #35465 · dotnet/runtime (original) (raw)

In .NET Core 3.x, work was done to make custom hosting easier. Support was added for an "application" and a "component". I need support for a hybrid between these two.

The general use case is for an application where its features are spread across native and managed code, with the entry point being in native code. The details of my specific use case are here: #34946.

It's like an "application" but not "component":

It's like a "component" but not an "application":

Unique aspects for this hybrid scenario:

Reasons to be implemented in .NET Core instead of by the custom host using coreclr directly:

Proposal

Original proposalAdd two new exported functions to `hostfxr` - `hostfxr_initialize_for_managed_host` and `hostfxr_create_delegate`. These two functions are similar to the existing `hostfxr_initialize_for_dotnet_command_line`/`hostfxr_run_app` and `hostfxr_initialize_for_runtime_config`/`hostfxr_get_runtime_delegate` function pairs in that the handle created from `hostfxr_initialize_for_managed_host` can only be used with `hostfxr_create_delegate`.

//
// Initializes the hosting components using an application
//
// Parameters:
//    managed_host_path
//      Path to the managed host assembly file
//    deps_json_path
//      Optional. Path to the .deps.json file
//    runtime_config_path
//      Optional. Path to the .runtimeconfig.json file
//    parameters
//      Optional. Additional parameters for initialization
//    host_context_handle
//      On success, this will be populated with an opaque value representing the initialized host context
//
// Return value:
//    Success          - Hosting components were successfully initialized
//    HostInvalidState - Hosting components are already initialized
//
// This function will find the .runtimeconfig.json and .deps.json corresponding to the given 
     application
// with which to resolve frameworks and dependencies and prepare everything needed to load the runtime.
//
// This function does not load the runtime.
//
typedef int32_t(HOSTFXR_CALLTYPE *hostfxr_initialize_for_managed_host_fn)(
    const char_t *managed_host_path,
    const char_t *deps_json_path,
    const char_t *runtime_config_path,
    const struct hostfxr_initialize_parameters *parameters,
    /*out*/ hostfxr_handle *host_context_handle);

//
// Create a native callable function pointer for a managed method from the currently loaded CoreCLR or from a newly created one.
//
// Parameters:
//     host_context_handle
//       Handle to the initialized host context
//     entry_point_assembly_name
//       Name of the assembly which holds the custom entry point
//     entry_point_type_name
//       Name of the type which holds the custom entry point
//     entry_point_method_name
//       Name of the method which is the custom entry point
//     delegate
//       Output parameter, the function stores a native callable function pointer to the delegate at the specified address
//
// Returns:
//     The error code result.
//
// The host_context_handle must have been initialized using hostfxr_initialize_for_managed_host.
// The assembly is loaded into the default AssemblyLoadContext.
//
typedef int32_t(HOSTFXR_CALLTYPE *hostfxr_create_delegate_fn)(
    const hostfxr_handle host_context_handle,
    const char_t *entry_point_assembly_name,
    const char_t *entry_point_type_name,
    const char_t *entry_point_method_name,
    /*out*/ void **delegate);

hostfxr_initialize_for_managed_host is essentially the same as hostfxr_initialize_for_dotnet_command_line but instead of argc/argv, it takes the application, deps.json, and runtimeconfig.json as explicit parameters.

hostfxr_create_delegate is simply a wrapper around the create delegate functionality of coreclr. hostfxr_get_runtime_delegate could not be reused since it always loads the target assembly into an isolated ALC (which is why it requires a handle from hostfxr_initialize_for_runtime_config - isolation is not supported in self-contained applications and it blocks on SCD).

Design document update and discussion: #36990