Ich komme kaum noch zum Bloggen, es findet sich immer etwas Wichtigeres. Zu dem fehlt momentan die Kick-Technologie zum bloggen.
Heute stelle ich zumindest mal meine Samples zu Unity 2.0 zum Download. Ich setze in fast all meinen Projekten Unity ein (außer ich muss etwas anderes nutzen), da es sehr simpel und effektiv ist. Unity ist bei Microsoft in eine wichtige Rolle geschlüpft. Heute habe ich gelernt, dass Unity im Exchange Server 2010 verwendet wird. Ich muss mir das zukünftig mal genauer anschauen. Das
Unity kann man Inline konfigurieren, oder per externer Konfiguration initiieren. Bei der Konfiguration per Code werden die Typen und Mappings direkt zum Container hinzugefügt. Die Inline Konfiguration nutze ich als Fallback, falls keine Konfiguration im Container vorhanden ist.
1: IUnityContainer container = new UnityContainer();
2: container.RegisterType<ITestInterface, TEstRunner>();
3: container.RegisterType<ITestInterface, TEstRunner>("specialVersion");
4: container.RegisterType<ITestInterface, TEstRunner>("singelton", new ContainerControlledLifetimeManager());
if(!container.IsRegistered<ITestInterface>())container.RegisterType<ITestInterface, TEstRunner>();
Zur Konfiguration mittels der Konfigurationsdatei muss der Container mit
new UnityContainer().LoadConfiguration();
initialisiert werden. Die Konfiguration könnte zum Beispiel so aussehen:
1: <configuration>
2: <configSections>
3: <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration"/>
4: </configSections>
5:
6: <unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
7: <alias alias="runner" type="PoC.Unity.Configuration.TEstRunner, PoC.Unity.Configuration"/>
8: <alias alias="Iservice" type="PoC.Unity.Configuration.ITestInterface, PoC.Unity.Configuration"/>
9: <container>
10: <register type="Iservice" mapTo="runner"/>
11: <register type="Iservice" mapTo="runner" name="specialVersion">
12: <lifetime type="perthread"/>
13: </register>
14: <register type="Iservice" mapTo="runner" name="singelton">
15: <lifetime type="singleton"/>
16: </register>
17: </container>
18: </unity>
19: </configuration>
Beim Erstellen eines Objektes durch den Container, können notwendige Abhängigkeiten ohne weitere Aktionen übergeben werden, sofern diese dem Container bekannt sind. (Injection) Ich nutze meistens Konstruktur Injection, da dies aus meiner Sicht die richtige Anwendung für erforderliche Komponenten ist.
1: public class TEstRunner : ITestInterface
2: {
3: private readonly IUnityContainer _container;
4: public TEstRunner(IUnityContainer container)
5: {
6: _container = container;
7: Console.WriteLine("Do I have a container? - " + (ReferenceEquals(_container, null) ? "no" : "yes"));
8: }
9: ...
10: }
11: container.Resolve<ITestInterface>().Run();
AOP ist etwas komplizierter, sobald es einmal läuft, auch wieder ganz einfach. ;) Allerdings muss man einige Utility-Klassen erstellen, so ist eine Attribute-Klasse und eine Implementierung des ICallHandler-Interface notwendig. Hier zumindest mal die Unity-Konfiguration:
1: IUnityContainer uc = new UnityContainer();
2: uc.AddNewExtension<Interception>();
3: uc.RegisterType<ITestInterface, TEstRunner>();
4: uc.Configure<Interception>()
5: .SetDefaultInterceptorFor<ITestInterface>(new InterfaceInterceptor());
Eigentlich ist es egal welchen DI/IoC Container man nutzt, es hilft den Code testbarer zu machen und reduziert Abhängigkeiten deutlich. Das Beste Bespiel für die Reduzierung von Abhängigkeiten erlebt man, wenn man mit Prism arbeitet.
Hier noch der Link zu einem schönen Video zu Unity (etwas veraltet): Unity Features and Futures at the patterns and practices Summit 2009
Samples: poc.unity.zip
Keine Kommentare:
Kommentar veröffentlichen