Search code examples
c#winformsinversion-of-controlautofac

Autofac Container in Windows Form Application


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.


Solution

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