I am wondering if anyone out there knows how I could create how could i use something like AutoFac to let me dynamically allow dll's to create there own forms and menu items to call them at run time.
So if I have an,
Employee.dll
- New Starter Form
- Certificate Form
Supplier.dll
- Supplier Detail From
- Products Form
In my winform app it would create a menu with this and when each one clicked load the relavent form up
People
Supplier
- Supplier Details
- Products
So I can add a new class library to the project and it would just add it to menu when it loads up.
Hope that make sense and someone can help me out.
Cheers
Aidan
The first things you have to do is to make your core application extensible. Let's see a simple example.
You will have to allow your external assembly to create item entry in your main app. To do this you can create a IMenuBuilder
interface in your main app.
public interface IMenuBuilder
{
void BuildMenu(IMenuContainer container);
}
This interface will allow external assembly to use a IMenuContainer
to create MenuEntry
. This interface can be defined like this :
public interface IMenuContainer
{
MenuStrip Menu { get; }
}
In your main form, you will have to implement IMenuContainer
and call all the IMenuBuilder
interface to allow them to create menu entry.
public partial class MainForm : Form, IMenuContainer
{
public MenuStrip Menu
{
get
{
return this.mnsMainApp;
}
}
private void MainForm_Load(Object sender, EventArgs e)
{
ILifetimeScope scope = ... // get the Autofac scope
foreach(IMenuBuilder menuBuilder in scope.Resolve<IEnumerable<IMenuBuilder>())
{
menuBuilder.BuildMenu(this);
}
}
}
In each external assembly, you will have to implement as much IMenuBuilder
as needed and one Autofac Module. In this module you will register those IMenuBuilder
.
public class XXXModule : Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<XXXMenuBuilder>()
.As<IMenuBuilder>();
}
}
Finally, in your core app, you will have to register all your modules provided by external assembly :
ContainerBuilder builder = new ContainerBuilder();
String path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
IEnumerable<Assembly> assemblies = Directory.GetFiles(path, "*.dll")
.Select(Assembly.LoadFrom);
builder.RegisterAssemblyModules(assemblies);