Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

199
Views
Inicializar interfaces en forma principal con inyección de dependencia

Este es mi código detrás del formulario 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(); }

y este es mi código detrás de 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); }

y así sucesivamente y así sucesivamente
y este es mi código detrás de la clase Program

 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); } }

el problema es que el valor de _expressionOfNeeds siempre es nulo y no puedo encontrar la manera de inicializarlo
Actualizar
Tengo muchos formularios y muchas interfaces.
Solo lo he limitado a un ejemplo para que el código no sea demasiado grande.

over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

Sugeriría crear una fábrica para obtener los formularios que necesita el formulario principal

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

asumiendo que los tipos que se crearán en este caso derivan de Form

la implementación utilizará el proveedor de servicios para resolver el tipo de formulario proporcionado

 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>(); } }

El formulario principal deberá depender de la fábrica para que pueda crear los formularios según sea necesario.

 //... 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); } //...

Asegúrese de que todo lo que debe resolver el proveedor de servicios esté registrado al inicio

 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); } }

De esa manera, todas las dependencias pueden ser resueltas e inyectadas por el contenedor, independientemente de cuántos formularios e interfaces haya.

over 4 years ago · Santiago Trujillo Report

0

Ya casi has llegado. Ha registrado el formulario y los servicios en el contenedor DI, pero olvidó inyectar las interfaces en el constructor de su formulario.

Debe agregar interfaces dependientes al constructor del formulario (solución preferida) u obtener una instancia de ellas del proveedor de servicios más adelante cuando lo necesite.

Puedes encontrar un ejemplo paso a paso en el siguiente post:

  • Cómo usar la inyección de dependencia en WinForms .

Suponiendo que tiene un MainForm que depende de IMyServie , entonces debería tener un constructor como este:

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

Luego, una vez que registre MainForm e IMyService en el contenedor DI y obtenga la instancia del proveedor de servicios, todo funcionará como se esperaba. Aquí está el punto de entrada principal:

 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>(); }); } }

Si por alguna razón (como lo que expliqué en la respuesta vinculada) necesita obtener una instancia de un servicio sin inyectarlo en el constructor, entonces puede usar Program.ServiceProvider.GetRequiredService<SomeFormOrService>() .

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!