Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

194
Visualizações
Initialize interfaces in main form with dependency injection

This my code behind form ExpressionOfNeeds

private readonly IExpressionOfNeeds _expressionOfNeeds;
public FrmExpressionOfNeeds(IExpressionOfNeeds expressionOfNeeds)
{
    InitializeComponent();
    _expressionOfNeeds = expressionOfNeeds;
}
private async void FrmExpressionOfNeeds_Load(object sender, EventArgs e)
{
    GCData.DataSource = await _expressionOfNeeds.GetAllExpressionOfNeeds();
}

and this my code behind MainForm

private readonly IExpressionOfNeeds _expressionOfNeeds;
private readonly IService2 _service2;
private readonly IService3 _service3;
//and so on and so forth
public XtraMain()
{
    InitializeComponent();
}
private void bbtnExpressionOfNeeds_ItemClick(object sender, ItemClickEventArgs e)
{
    FrmExpressionOfNeeds frme = new(_expressionOfNeeds)
    {
        Name = "FrmExpressionOfNeeds"

    };
    ViewChildForm(frme);
}
private void bbtnForm2_ItemClick(object sender, ItemClickEventArgs e)
{
    Form2 frme = new(_service2)
    {
        Name = "Form2"

    };
    ViewChildForm(frme);
}
private void bbtnForm3_ItemClick(object sender, ItemClickEventArgs e)
{
    Form3 frme = new(_service3)
    {
        Name = "Form3"

    };
    ViewChildForm(frme);
}

and so on and so forth
and this is my code behind Program class

static void Main()
{
    var builder = new HostBuilder()
                 .ConfigureServices((hostContext, services) =>
                 {
                     services.AddScoped<XtraMain>();
                     services.AddSingleton<ISqlDataAccess, SqlDataAccess>();
                     services.AddSingleton<IExpressionOfNeeds, ExpressionOfNeeds>();
                 });
    var host = builder.Build();
    using (var serviceScope = host.Services.CreateScope())
    {
        var services = serviceScope.ServiceProvider;
        var mainform = services.GetRequiredService<XtraMain>();
        Application.Run(mainform);
    }
}

the problem is that the value of _expressionOfNeeds is always null and I can't find a way to Initialize it
Update
I have lots of forms and lots of Interfaces
I've only limited it to one example so the code isn't too big.

over 4 years ago · Santiago Trujillo
2 Respostas
Responde à pergunta

0

I would suggest creating a factory to get the forms needed by the main form

public interface IFormFactory {
    TForm Create<TForm>() where TForm : Form;
}

assuming the types to be created in this case all derive from Form

the implementation will use the service provider to resolve provided form type

public class FormFactory: IFormFactory {
    private readonly IServiceProvider services;

    public FormFactory(IServiceProvider services) {
        this.services = services;
    }

    public TForm Create<TForm>() where TForm : Form {
        return services.GetRequiredService<TForm>();
    }
}

The main form will need to depend on the factory so that it can create the forms as needed

//...

private readonly IFormFactory factory;

public XtraMain(IFormFactory factory) {
    InitializeComponent();
    this.factory = factory;
}
private void bbtnExpressionOfNeeds_ItemClick(object sender, ItemClickEventArgs e) {
    FrmExpressionOfNeeds frme = factory.Create<FrmExpressionOfNeeds>();
    frme.Name = "FrmExpressionOfNeeds";
    ViewChildForm(frme);
}
private void bbtnForm2_ItemClick(object sender, ItemClickEventArgs e) {
    Form2 frme = factory.Create<Form2>();
    frme.Name = "Form2";
    ViewChildForm(frme);
}
private void bbtnForm3_ItemClick(object sender, ItemClickEventArgs e) {
    Form3 frme = factory.Create<Form3>();
    frme.Name = "Form3";
    ViewChildForm(frme);
}

//...

Make sure everything to be resolved by the service provider is registered at startup

static void Main() {
    var builder = new HostBuilder()
                 .ConfigureServices((hostContext, services) => {
                    services.AddScoped<XtraMain>();
                    services.AddTransient<FrmExpressionOfNeeds>();
                    services.AddTransient<Form2>();
                    services.AddTransient<Form3>();
                    services.AddSingleton<ISqlDataAccess, SqlDataAccess>();
                    services.AddSingleton<IExpressionOfNeeds, ExpressionOfNeeds>();
                    services.AddSingleton<IFormFactory, FormFactory>();
                 });
    var host = builder.Build();
    using (var serviceScope = host.Services.CreateScope()) {
        IServiceProvider services = serviceScope.ServiceProvider;
        XtraMain mainform = services.GetRequiredService<XtraMain>();
        Application.Run(mainform);
    }
}

That way all dependencies can be resolved and injected by the container regardless of how many forms and interfaces there are.

over 4 years ago · Santiago Trujillo Relatório

0

You are almost there. You have registered the Form and services into DI container, but forgot to inject the interfaces into your form's constructor.

You have to either add dependent interfaces to the form's constructor (preferred solution), or get an instance of them from the service provider later when you need.

You can find a step by step example in the following post:

  • How to use dependency injection in WinForms.

Assuming you have a MainForm which has a dependency to IMyServie, then you should have a constructor like this:

IMyService _myService;
public MainForm(IMyService myService)
{
    _myService = myService;
}

Then once you register MainForm and IMyService into the DI container and get the instance from service provider, everything will work as expected. Here is the main entry point:

static class Program
{
    public static IServiceProvider ServiceProvider { get; private set; }

    [STAThread]
    static void Main()
    {
        ApplicationConfiguration.Initialize();
        var host = CreateHostBuilder().Build();
        ServiceProvider = host.Services;
        Application.Run(ServiceProvider.GetRequiredService<MainForm>());
    }

    static IHostBuilder CreateHostBuilder()
    {
        return Host.CreateDefaultBuilder()
            .ConfigureServices((context, services)=>{
                services.AddTransient<IMyService, MyService>();
                services.AddTransient<MainForm>();
            });
    }
}

If for some reason (like what I explained in the linked answer) you need to get an instance of a service without injecting it in the constructor, then you can use Program.ServiceProvider.GetRequiredService<SomeFormOrService>().

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda