Skip to content
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

Request for Generic Host (.NET Core 3) + Prism + WPF sample - Can contribute #178

Closed
bmarinov opened this issue Jan 24, 2020 · 2 comments
Closed
Labels

Comments

@bmarinov
Copy link

bmarinov commented Jan 24, 2020

Turns out I cannot read and posted the issue here instead in the Prism samples repo. Im sorry for that. Nothing to see here, move along.

Original post

Is your feature request related to a problem? Please describe.

I am missing a sample or some documentation explaining the correct way to handle this. I want to set up a .NET Core WPF application which uses Prism and whose Lifetime / DI / Configuration is controlled (or supported) by a Generic Host.
In my case I am utilizing DryIoC as my ioc container of choice.

Right now WPF does not do a great job of using newer framework features, there are some open issues on GH like dotnet/wpf:499. So even if the WPF integration will not be perfect, some aspects can already be put to good use: IoC, Configuration and Hosted Services for background tasks.

Describe the solution you'd like
Clear guidelines for bootstrapping an application using a Generic Host, sample included.

I am having trouble finding definitive information on instantiating the IoC container myself. There is a hook that seems to be doing that - CreateContainerExtension(). Is this the correct way to go about it? If yes, is its intended use documented and if not - can we improve the documentation?

Describe alternatives you've considered

I managed to get things going with a couple of extra lines, but I'm sure that there are better ways to go about that (eg utilizing the aforementioned CreateContainerExtension method).

Additional dependencies:

  • Microsoft.Extensions.Hosting - this dependency is for the generic host feature.
  • DryIoc.Microsoft.DependencyInjection - package with extension methods for the dryioc adapter, usually used in the context of ASPNET Core.

The App.xaml.cs actually looks alright, services can be registered as usual and resolved via base.Container and via _host.Services since im basically just adding more registrations to the instantiated container.

// App.xaml.cs

protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
    containerRegistry.Register<ServiceA>();
}

protected override Window CreateShell()
{
    _host = new HostBuilder()
        .ConfigureServices(x =>
        {
            x.AddTransient<ServiceB>();
        })
        .UseServiceProviderFactory(new DryIocServiceProviderFactory(Container))
        .Build();

    _host.Start();
    // ServiceA and ServiceB can be resolved here.

    return _host.Services.GetService<MainWindow>();
}

While implementing the DryIoC Service Provider Factory it became obvious that I'm going down the wrong path. As you will see, I am taking the instantiated container and casting it to the known underlying type. Normally you would new up a container in CreateBuilder so this current implementation feels wrong.

// DryIocServiceProviderFactory.cs
internal class DryIocServiceProviderFactory : IServiceProviderFactory<IContainer>
{
    private readonly DryIocContainerExtension _containerProvider;

    public DryIocServiceProviderFactory(IContainerProvider containerProvider)
    {
        // I should not be doing this..
        _containerProvider = containerProvider as DryIocContainerExtension;
    }

    public IContainer CreateBuilder(IServiceCollection services)
    {
        return _containerProvider.Instance.WithDependencyInjectionAdapter(services);
    }

    public IServiceProvider CreateServiceProvider(IContainer containerBuilder)
    {
        return containerBuilder.Resolve<IServiceProvider>();
    }
}

Describe suggestions on how to achieve the feature

So if I am correct, I need to somehow use the CreateContainerExtension() method.
The following does not work, Prism services are missing from the container and cannot be resolved.

protected override IContainerExtension CreateContainerExtension()
{
    return new DryIocContainerExtension(new DryIoc.Container());
}

I thought that these would get registered in the container I return from this method.

Hopefully I did not miss anything obvious in the documentation, I searched but found nothing. I would love to contribute to the project and push such a sample, but before doing that I need a bit of hand holding. Thanks!

@richbryant
Copy link
Contributor

richbryant commented Jan 24, 2020

With all due respect, are you sure this is a ReactiveUI issue?

@bmarinov
Copy link
Author

bmarinov commented Jan 24, 2020

With all due respect, are you sure this is a ReactiveUI issue?

I am an idiot, I created the issue and pasted this in the browser wrong tab. How I delete myself out of existence :(

@lock lock bot added the outdated label Apr 25, 2020
@lock lock bot locked and limited conversation to collaborators Apr 25, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

2 participants