Reputation: 1287
I am trying to learn Autofac. I can't find a working example for Winforms. In my program.cs
I have this:
public static IContainer Container { get; private set; }
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
private static void Main()
{
var builder = new ContainerBuilder();
builder.Register(c => new MyContext());
Container = builder.Build();
...
using (var loginForm = new LoginForm(new MyContext()))
{
DialogResult results;
do
{
results = loginForm.ShowDialog();
if (results == DialogResult.Cancel)
Environment.Exit(1);
} while (results != DialogResult.OK);
UserName = loginForm.ValidatedUserName;
}
}
MyContext()
is a DbContext. I want to inject MyContext()
into my LoginForm()
, but I haven't quite figured that out. The first few lines of LoginForm()
:
public partial class LoginForm : Form
{
private readonly MyContext _context;
public LoginForm(MyContext context)
{
InitializeComponent();
_context = context;
}
...
}
Any suggestions would be appreciated.
Upvotes: 2
Views: 2435
Reputation: 934
Best practice is to register the classes and the form that the service classes are used by it. Then create the form instance by container. By this method, dependency injection is implemented. Add the codes in Program.cs
var builder = new ContainerBuilder();
builder.RegisterInstance(new AService()).As<IAService>();
builder.RegisterType<LoginForm>();
container = builder.Build();
using (var scope = container.BeginLifetimeScope())
{
var loginForm= scope.Resolve<LoginForm>();
Application.Run(loginForm);
}
Upvotes: 0
Reputation: 38860
Register the form too:
var builder = new ContainerBuilder();
builder.RegisterType<MyContext>();
builder.RegisterType<LoginForm>();
Container = builder.Build();
And then resolve the form from the container:
using (var loginForm = Container.Resolve<LoginForm>())
{
DialogResult results;
do
{
results = loginForm.ShowDialog();
if (results == DialogResult.Cancel)
Environment.Exit(1);
} while (results != DialogResult.OK);
UserName = loginForm.ValidatedUserName;
}
Then MyContext
will automatically be injected when the form is resolved. By default Autofac registrations are registered as "self" (i.e. they can be resolved as their own type) and "instance per dependency" (you get a new one each time you resolve it), so you are safe to keep the using
in this case.
Upvotes: 6
Reputation: 2988
Disclaimer: I haven't used Autofac before.
Basing my solution off the documentation, you will need to change:
builder.Register(c => new MyContext());
to
builder.Register(c => new MyContext()).AsSelf();
This is so that Autofac can find the dependency that needs to be created.
You will then need to change:
using (var loginForm = new LoginForm(new MyContext()))
{
...
}
To be:
using (var scope = Container.BeginLifetimeScope())
{
using (var loginForm = new LoginForm(scope.Resolve<MyContext>()))
{
...
}
}
The line scope.Resolve<MyContext>()
will create the dependency based on what you've registered.
Upvotes: 0