Sto cercando di introdurre DI (con Autofac) in un'applicazione Windows Form esistente.DI (Autofac) in un'architettura plug-in: è un contenitore DI separato per plug-in OK?
Questa applicazione ha un'architettura plug-in di base in cui ogni plug-in visualizza il proprio modulo. All'avvio, le scansioni delle applicazioni assemblee registrati per i tipi che implementano IPlugin
, e quindi attiva queste usando Activator.CreateInstance
:
public interface IPlugin
{
Form MainForm { get; }
}
io non posso cambiamento questo dato quadro. Ciò significa che ogni classe di plug-in viene istanziata tramite mezzi non-DI, e mi sembra quindi che dovrò riavviare un contenitore DI separato per ciascun plugin.
La mia domanda è, sta creando un separato ContainerBuilder
e contenitore per plug-in OK e comunque ragionevolmente efficiente? (Ci saranno circa 10 diversi plugin.) O dovrebbe esserci solo un contenitore DI per l'intera applicazione?
Ho fornito un codice di esempio della mia soluzione corrente di seguito.
using Autofac;
using System.Windows.Forms;
public class Plugin : IPlugin // instantiated by Activator
{
public Form MainForm { get; private set; }
public Plugin() // parameter-less constructor required by plugin framework
{
var builder = new ContainerBuilder();
builder.RegisterModule(new Configuration());
var container = builder.Build();
MainForm = container.Resolve<MainForm>();
//^preferred to new MainForm(...) because this way, I can take
// advantage of having dependencies auto-wired by the container.
}
}
internal class Configuration : Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<MainForm>().SingleInstance();
// ... more plugin-specific registrations go here...
}
}
internal class MainForm : Form { /* ... */ }
Io non sono sicuro se anche la creazione di un contenitore nel costruttore plug-in e poi semplicemente dimenticare a questo proposito, ma lasciando a fare auto-cablaggio in background, è OK?
Grazie per la risposta, @ Mark. Se ti capisco bene, il mio codice di esempio segue già il modello RRR ... giusto? (Con l'eccezione che non rilascio il contenitore, poiché deve rimanere attivo almeno fino a quando il componente root 'MainForm'. Suppongo che il modo ideale per farlo sia rendere i plugin' IDisposable' e rilasciare il contenitore nel metodo 'Dispose'.) – stakx
Non c'è nulla nel codice che suggerisce di non seguire RRR, ma è difficile da dire. In ogni caso, tieni presente che lo stile di vita SingleInstance definisce solo Singleton con ambito contenitore. Non è un vero Singleton, quindi non puoi condividere la MainForm in questo modo. –