I am new to IoC, especially with Autofac. Some days I was confused with IoC in the Windows Application Form. The obstacle is how to display (like: Show, ShowDialog) the form that has been registered. While IContainer can only be accessed locally (private) Program.cs.
Actually, can IoC be used in the Windows Application Form? I gave a sample code that confused me.
#
# Demo.Core Project
#
namespace Demo.Core.Repository
{
public interface IBaseRepository<T>
{
DbConnection CreateConnection();
IEnumerable<T> Get(IDbTransaction transaction = null, int? commandTimeout = null);
}
public abstract class BaseRepository<T> : IBaseRepository<T> where T : class
{
public DbConnection CreateConnection()
{
return new SqlConnection("Data Source=localhost;User ID=sa;Password=Default!3;Initial Catalog=DemoIoC;");
}
public IEnumerable<T> Get(IDbTransaction transaction = null, int? commandTimeout = null)
{
using (var connection = CreateConnection())
return connection.GetAll<T>(transaction, commandTimeout);
}
}
public interface IUserRepository : IBaseRepository<User> { }
public class UserRepository : BaseRepository<User>, IUserRepository { }
}
namespace Demo.Core.Models
{
public class User
{
public int Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
}
}
#
# Demo.Winform Project
#
using Demo.Core.Models;
using Demo.Core.Repository;
namespace Demo.Winform
{
static class Program
{
public static IContainer Container;
[STAThread]
static void Main()
{
Container = Configure();
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainForm());
}
static IContainer Configure()
{
var builder = new ContainerBuilder();
builder.RegisterType<UserRepository>().As<IUserRepository>();
builder.RegisterType<UserManagerForm>();
return builder.Build();
}
}
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
button1.Click += new EventHandler(delegate (object sender, EventArgs e)
{
using (var container = *** HOW TO GET CONTAINER ? ***)
{
Form manager = container.Resolve<UserManagerForm>();
manager.ShowDialog();
}
});
}
}
public partial class UserManagerForm : Form
{
private readonly IUserRepository repository;
public UserForm(IUserRepository repository) : this()
{
this.repository = repository;
}
public UserForm()
{
InitializeComponent();
}
protected override void OnShown(EventArgs e)
{
base.OnShown(e);
listBox1.ValueMember = "Id";
listBox1.DisplayMember = "Name";
listBox1.DataSource = repository.Get();
}
}
}
I have read how to register form types in containers: Autofac - Register all Windows Forms. But the question is, how do I resolve the form that was registered and show form?
Thank you.
This worked for me ,You just get the service from the container \
static class Program
{
public static IContainer Container;
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Container = Configure();
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1(Container.Resolve<IWindowsFormsApp3Client>()));
}
static Autofac.IContainer Configure()
{
var builder = new ContainerBuilder();
builder.Register<IWindowsFormsApp3Client>(ctor => new WindowsFormsApp3Client(new Uri("https://localhost:44381"), new CustomLoginCredentials()))
.AsImplementedInterfaces();
// builder.RegisterType<WindowsFormsApp3Client>().As<IWindowsFormsApp3Client>();
builder.RegisterType<Form1>();
return builder.Build();
}
}
public class CustomLoginCredentials : ServiceClientCredentials
{
private string AuthenticationToken { get; set; }
public override async Task ProcessHttpRequestAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
// AuthenticationToken = Extensions.GetAppsettingsToken()?.AccessToken;
if (AuthenticationToken != null)
{
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", AuthenticationToken);
}
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
await base.ProcessHttpRequestAsync(request, cancellationToken);
}
}