6 Stimmen

Was sind die Vor- und Nachteile von Autofac?

Ich habe über Autofac gelesen, dass es schnell ist. Ich habe mir die Kodierung angesehen, und sie ist ziemlich toll. Aber ich bin mir nicht ganz sicher, wie ich es benutzen soll. Ich habe StructureMap verwendet, und es hat eine statische ObjectFactory. Ninject hat den Kernel, aber auf den Google-Seiten von Autofac wird empfohlen, so etwas zu tun:

using( var resolver = builder.Build() ){
   var whatINeed = resolver.Resolve<INeedThisService>();
}

Es ist eine WinForms-Anwendung, so dass ich einen ungültigen Objektstatus von tun die oben, so dass ich wechselte zu einem globalen IContainer, und tat es auf diese Weise

 using( var resolver = Program.Container.CreateInnerContainer() )
 {
     var whatINeed = resolver.Resolve<INeedThisService>();
 }

Ich habe es etwa 3 oder 5 Mal benutzt. Aber ist das effizient? Oder sollte ich einfach etwas tun wie

 var whatINeed = Program.Resolve<INeedThisService>()

und unter der Bettdecke

 internal static TServervice Resolver<TService>(){
       if(_container == null ) _container = builder.Build();
       return _container.Resolve<TService>();
 }

Welche würden Sie verwenden und warum? Gibt es auch eine Strafe für die Arbeit mit CreateInnerContainer()?

9voto

Mark Lindell Punkte 852

Ich bin kein AutoFac-Experte, habe aber Erfahrung mit anderen Ioc-Containern. Ich dachte, diese Frage würde mir einen Grund geben, AutoFac auszuprobieren.

Entwürfe, die auf Ioc-Containern basieren, sollten darauf abzielen, den gesamten Code vom Zugriff auf den Container zu isolieren, außer am Einstiegspunkt oder auf Host-Ebene. Ich habe das folgende Beispiel mit AutoFac und WinForms erstellt, um zu zeigen, wie ein Formular über seinen Konstruktor auf einen Dienst zugreifen kann.

Ich bin mir nicht ganz sicher, warum Sie dachten, Sie bräuchten den Innenbehälter. Vielleicht können Sie sich dazu äußern und ich kann Ihnen eine ausführlichere Antwort geben.

static class Program
{
    [STAThread]
    static void Main()
    {
        var builder = new ContainerBuilder();
        builder.Register<TheService>().As<INeedThisService>();
        builder.Register(f => new Form1(f.Resolve<INeedThisService>())).As<Form1>();

        using (var container = builder.Build())
        {
            Application.Run(container.Resolve<Form1>());
        }

    }
}

public interface INeedThisService { }

public class TheService : INeedThisService
{
    public TheService() { Console.WriteLine("ctor ThisService"); }
}

public partial class Form1 : Form
{
    public Form1(INeedThisService service)
    {
        Console.WriteLine("ctor Form1");
        InitializeComponent();
    }
}

5voto

andrey.tsykunov Punkte 2806

1) Aus den von Ihnen genannten Beispielen könnte ich die Vermutung ableiten, dass Sie versuchen, den IOC-Container in erster Linie als Service Locator zu verwenden. Obwohl fast alle Container dies unterstützen, wäre die Hauptverwendung Injektion von Abhängigkeiten . Das bedeutet, dass Sie es vermeiden sollten, die Resolve-Methode überhaupt aufzurufen und den Container alle Abhängigkeiten für Sie injizieren lassen sollten. Die Unterschiede zwischen zwei dieser Methoden (Service Locator und Dependency Injection) würden den Rahmen dieses Themas sprengen.

2) Wenn Sie ihn trotzdem als Dienstlokalisierer verwenden möchten, können Sie einfach den Root-Container ( Programm.Container in Ihrem Fall), ohne innere Container zu erstellen. Die Reihenfolge wäre:

  • ContainerBuilder erstellen
  • Registrieren Sie Ihre Komponenten im Builder
  • Wurzel-Container erstellen: builder.Build()
  • Zugriff auf den Root-Container zur Auflösung von Komponenteninstanzen

3) Container-Hierarchien können in den Szenarien nützlich sein, in denen Sie Singleton-Verhalten in verschiedenen Bereichen benötigen:

  • Global \ Session \ Request (Web-Anwendungen)
  • Anwendung \ Plugin (Desktop-Plugin-basierte Anwendungen)

Übrigens ermutigt Autofac die Menschen zur Nutzung markierte Kontexte um solche Probleme zu lösen:

3voto

Nicholas Blumhardt Punkte 27718

Wie Mark Lindell feststellte, ist es im Allgemeinen nicht erforderlich, in einer Autofac-Anwendung direkt auf den Container zuzugreifen.

Es wird empfohlen, einmalig beim Start der Anwendung darauf zuzugreifen, wie es Mark getan hat.

Andere Komponenten, die später Objekte erzeugen müssen, können einen Konstruktorparameter vom Typ IContext deklarieren, der von Autofac automatisch injiziert wird.

Eine Alternative, die keine Abhängigkeit von der Autofac-Baugruppe erfordert, ist die Verwendung von generierten Fabriken, wie unter beschrieben: http://code.google.com/p/autofac/wiki/DelegateFactories

Ich hoffe, das hilft!

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X