Welche Vor- und Nachteile hat die Verwendung von Enterprise Library Unity im Vergleich zu anderen IoC-Containern (Windsor, Spring.Net, Autofac ..)?
Welche Vor- und Nachteile hat die Verwendung von Enterprise Library Unity im Vergleich zu anderen IoC-Containern (Windsor, Spring.Net, Autofac ..)?
Antworten:
Ich bereite eine Präsentation für eine Benutzergruppe vor. Als solches habe ich nur ein paar von ihnen durchgesehen. Nämlich: AutoFac, MEF, Ninject, Spring.Net, StructureMap, Unity und Windsor.
Ich wollte den 90% -Fall vorführen (Konstruktorinjektion, für die die Leute sowieso sowieso ein IOC verwenden). Sie können die Lösung hier überprüfen (VS2008)
Daher gibt es einige wesentliche Unterschiede:
Jeder von ihnen hat auch andere Funktionen (einige haben AOP und bessere Gizmos, aber im Allgemeinen möchte ich nur, dass ein IOC Objekte für mich erstellt und abruft).
Hinweis: Die Unterschiede zwischen den verschiedenen Bibliotheksobjektabrufen können mithilfe des CommonServiceLocator aufgehoben werden: http://www.codeplex.com/CommonServiceLocator
So bleibt uns die Initialisierung, die auf zwei Arten erfolgt: über Code oder über die XML-Konfiguration (app.config / web.config / custom.config). Einige unterstützen beide, andere nur einen. Ich sollte beachten: Einige verwenden Attribute, um die IoC voranzutreiben.
Hier ist meine Einschätzung der Unterschiede:
Nur Code-Initialisierung (mit Attributen). Ich hoffe du magst Lambdas. Der Initialisierungscode sieht folgendermaßen aus:
IKernel kernel = new StandardKernel(
new InlineModule(
x => x.Bind<ICustomerRepository>().To<CustomerRepository>(),
x => x.Bind<ICustomerService>().To<CustomerService>(),
x => x.Bind<Form1>().ToSelf()
));
Initialisierungscode oder XML oder Attribute. v2.5 ist auch sehr lambda'y. Alles in allem ist dies einer meiner Favoriten. Einige sehr interessante Ideen zur Verwendung von Attributen durch StructureMap.
ObjectFactory.Initialize(x =>
{
x.UseDefaultStructureMapConfigFile = false;
x.ForRequestedType<ICustomerRepository>()
.TheDefaultIsConcreteType<CustomerRepository>()
.CacheBy(InstanceScope.Singleton);
x.ForRequestedType<ICustomerService>()
.TheDefaultIsConcreteType<CustomerService>()
.CacheBy(InstanceScope.Singleton);
x.ForConcreteType<Form1>();
});
Initialisierungscode und XML. Schöne Bibliothek, aber die XML-Konfiguration ist ein Problem. Tolle Bibliothek für Microsoft oder die Highway-Läden. Die Code-Initialisierung ist einfach:
container.RegisterType<ICustomerRepository, CustomerRepository>()
.RegisterType<ICustomerService, CustomerService>();
XML nur so nah wie ich es beurteilen kann. Aber für die Funktionalität macht Spring.Net alles unter der Sonne, was ein IoC kann. Da die einzige Möglichkeit zur Vereinheitlichung jedoch XML ist, wird dies von .net-Shops im Allgemeinen vermieden. Viele .net / Java-Shops verwenden Spring.Net jedoch aufgrund der Ähnlichkeit zwischen der .net-Version von Spring.Net und dem Java Spring-Projekt.
Hinweis : Die Konfiguration im Code ist jetzt mit der Einführung von Spring.NET CodeConfig möglich .
XML und Code. Wie Spring.Net wird Windsor alles tun, was Sie sich wünschen können. Windsor ist wahrscheinlich einer der beliebtesten IoC-Container.
IWindsorContainer container = new WindsorContainer();
container.AddComponentWithLifestyle<ICustomerRepository, CustomerRepository>("CustomerRepository", LifestyleType.Singleton);
container.AddComponentWithLifestyle<ICustomerService, CustomerService>("CustomerService",LifestyleType.Singleton);
container.AddComponent<Form1>("Form1");
Kann sowohl XML als auch Code mischen (mit v1.2). Schöne einfache IoC-Bibliothek. Scheint die Grundlagen mit wenig Aufhebens zu machen. Unterstützt verschachtelte Container mit lokalem Umfang der Komponenten und einem genau definierten Lebensdauermanagement.
So initialisieren Sie es:
var builder = new ContainerBuilder();
builder.Register<CustomerRepository>()
.As<ICustomerRepository>()
.ContainerScoped();
builder.Register<CustomerService>()
.As<ICustomerService>()
.ContainerScoped();
builder.Register<Form1>();
Wenn ich mich heute entscheiden müsste: Ich würde wahrscheinlich mit StructureMap gehen. Es bietet die beste Unterstützung für C # 3.0-Sprachfunktionen und die größte Flexibilität bei der Initialisierung.
Hinweis : Chris Brandsma hat seine ursprüngliche Antwort in einen Blog-Beitrag umgewandelt .
Soweit ich gesehen habe, sind sie bis auf ein paar Implementierungsdetails hier und da ziemlich gleich. Der größte Vorteil von Unity gegenüber der Konkurrenz besteht darin, dass es von Microsoft bereitgestellt wird. Es gibt viele Unternehmen, die Angst vor OSS haben.
Ein Nachteil ist, dass es ziemlich neu ist, so dass es möglicherweise Fehler gibt, die die älteren Spieler bereits behoben haben.
Trotzdem möchten Sie dies vielleicht überprüfen .
Alter Thread, aber da dies das erste ist, was Google mir gezeigt hat, als ich Unity vs spring.net eingegeben habe ...
Spring führt jetzt CodeConfig aus, wenn Ihnen die XML-Konfiguration nicht gefällt
http://www.springframework.net/codeconfig/doc-latest/reference/html/
Außerdem ist Spring viel mehr als nur ein DI-Container. Wenn Sie sich den Abschnitt 'Module' in den Dokumenten ansehen, ist der DI-Container die Grundlage für den riesigen Stapel von Dingen, die er tut.
Korrigieren Sie mich, wenn ich mich irre, aber ich denke, Autofac selbst unterstützt die XML-Konfiguration, wie in diesem Link aufgeführt: Autofac XML-Konfiguration
Spring verfügt über eine Funktion, mit der Parameter basierend auf dem Parameternamen oder der Position in den Konstruktor oder die Eigenschaft eingefügt werden können. Dies ist sehr nützlich, wenn der Parameter oder die Eigenschaft ein einfacher Typ ist (z. B. eine Ganzzahl, ein Boolescher Wert). Siehe das Beispiel hier . Ich glaube nicht, dass dies die Unfähigkeit von Spring, Konfigurationen im Code durchzuführen, wirklich wettmacht.
Windsor kann dies auch und dies in Code, der nicht konfiguriert ist. (Korrigieren Sie mich, wenn ich falsch liege, ich gehe nur über das, was ich hier gehört habe).
Ich würde gerne wissen, ob Unity dies kann.
Eine Sache zu beachten: Ninject ist der einzige IoC-Container, der kontextbezogene Abhängigkeitsinjektionen unterstützt (gemäß ihrer Website). Da ich jedoch keine Erfahrung mit anderen IoC-Containern habe, kann ich nicht sagen, ob dies zutrifft.
Um meine 2 Cent hinzuzufügen, habe ich sowohl StructureMap als auch Unity ausprobiert. Ich fand StructureMap schlecht / irreführend dokumentiert, ein Problem beim Konfigurieren und eine klobige Verwendung. Ebenso scheint es keine Szenarien wie das Überschreiben von Konstruktorargumenten zur Auflösungszeit zu unterstützen, was für mich ein wichtiger Verwendungspunkt war. Also ließ ich es fallen und ging mit Unity und ließ es in ungefähr 20 Minuten tun, was ich wollte.
Ich persönlich benutze Unity, aber nur, weil es von Microsoft stammt. Ich bedauere die Entscheidung aus einem Grund: Das größte Problem ist ein großer "Fehler", der dazu führt, dass ständig Ausnahmen ausgelöst werden. Sie können die Ausnahmen beim Debuggen ignorieren. Es verlangsamt jedoch Ihre Anwendung enorm, wenn Sie darauf stoßen, da das Auslösen einer Ausnahme eine teure Operation ist. Zum Beispiel "behebe" ich diese Ausnahme derzeit an einer Stelle in meinem Code, an der die Ausnahmen von Unity die Renderzeit einer Seite um weitere 4 Sekunden verlängern . Weitere Details und eine Problemumgehung finden Sie unter:
Kann Unity dazu gebracht werden, SynchronizationLockException nicht ständig auszulösen?