Schlagwort-Archive: CastleWindsor

Open Closed Principle mit 2 Zeilen Code

In meinem Video zu 60 Minuten mit der Pfadfinderregel war ich noch die Lösung zu Castle.Windsor schuldig. In diesem Webcast zeige ich wie die CollectionResolver-Funktionalität genutzt werden kann, um nachträglich hinzugefügte Implementierungen automatisch im Container zu registrieren.

Dadurch kann das OCP vollständig eingehalten werden, da lediglich eine neue Klasse hinzugefügt werden und der restliche Code nicht angefasst werden muss. Den Code habe ich hier zur Verfügung gestellt. Fragen und Feedback einfach in die Kommentare.

public class Installer : IWindsorInstaller
{
/// <summary>
/// Performs the installation in the <see cref="T:Castle.Windsor.IWindsorContainer" />.
/// </summary>
/// <param name="container">The container.</param>
/// <param name="store">The configuration store.</param>
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Kernel.Resolver.AddSubResolver(new Castle.MicroKernel.Resolvers.SpecializedResolvers.CollectionResolver(container.Kernel));
container.Register(Components().ToArray());
}
private static IEnumerable<IRegistration> Components()
{
//have a look at https://github.com/castleproject/Windsor/blob/master/docs/registering-components-by-conventions.md
yield return Classes //non abstract classes; you could also use Types.* for more choices
.FromThisAssembly() //should be clear
.IncludeNonPublicTypes() //since my implementations are internal, only the interface is public
.BasedOn<IFoo>() //every class that implements this interface
.WithService.Base() //also possible: .WithServiceFromInterface()
.LifestyleTransient();
yield return Component
.For<IBar>()
.ImplementedBy<Bar>()
.LifestyleTransient();
}
}

Durch Klicken auf das Bild geht es zum Video

Durch Klicken auf das Bild geht es zum Video

Werbung

Die großen 4: Pfadfinderregel, Wirtschaftlichkeit, Clean Code, SOLID Principles

Was ist damit gemeint? Gemäß der Pfadfinderregel soll ein Entwickler Code immer besser hinterlassen, als er ihn vorgefunden hat. Clean Code oder guter Code ist häufig dann erreicht, wenn das Mindestmaß an essentiellen Code Prinzipien umgesetzt ist. Das sind die sogenannten SOLID Principles. Jedoch ist guter Code kein Selbstzweck, sondern dient dem größeren Ziel der Wirtschaftlichkeit.

Im folgenden Video zeige ich an einem Praxisbeispiel, wie ich bei einem bestehendem, eher unwichtigem Projekt vorgegangen bin. Timeboxed in 1h so viel refaktorisieren und den Code verbessern wie möglich. Dabei gehe ich auf Prinzipien wie DRY und OCP ein und zeige Techniken wie DI, sowie Tools wie den IoC Container Castle Windsor.

Feedback nehme ich wie immer gerne mit. Wenn ihr mehr von solchen Videos sehen wollt, schreibt mir das in die Kommentare, damit ich weiß: Hier lohnt es sich mehr zu machen.

Zum YouTube Video

Durch Klicken auf das Bild geht es zum Video

Lazy Loading mit IoC

Update vom 04.09.2013: Beachtet bitte die Kommentare. Das Lazy-Feature kann auch erhebliche Performance-Einbußen zur Folge haben. Es kommt darauf, was der Konstruktur des Lazy-Objekts noch an Abhängigkeiten hat und welche Logik in selbigem noch ausgeführt wird.

In diesem Webcast zeige ich welche Möglichkeiten Castle.Windsor für das Lazy Loading von Abhängigkeiten bietet. Das Feature wurde in Version 3 eingeführt. Weiterführenden Inhalt welche Performance Gedanken dahinter stecken und wann idealerweise der Graph des Container geladen werden sollte, findet ihr hier und hier.

Für diejenigen, die einen anderen Container nutzen: Falls euer Framework die Funktionalität nicht out-of-the-box mitliefert, so stellt sich eine eigene Lösung nicht als allzu schwierig heraus. In dem oben zuletzt erwähnten Link gibt es dazu ein Code Sample.

Als grobe Richtlinie kann man sich merken:

Das Laden von weiteren Abhängigkeiten wird v.a. dann “teuer”, wenn die Implementierungen in Assemblies liegen, die noch nicht geladen wurden.

Castle Windsor Dependencies Tracking

Deployments für Anwendungen zu erstellen, welche modular über einen IoC Container wie Castle.Windsor aufgebaut sind, ist nicht ganz simpel. Zumindest ging es mir so, als ich vor der Herausforderung stand eine Konsolenanwendung zu deployen, welche im Einstiegspunkt eine Komponente auflöst und darauf eine Methode aufruft, die den gesamten Bearbeitungsprozess startet. Alle weiteren Abhängigkeiten werden dann über den internen Graphen des Containers aufgelöst. Findet er eine Komponente nicht, kommt es zur Exception:

image

Ich halte es in meinen Projekten so, dass die Kontrakte immer in einer separaten Assembly liegen. Als Namenskonvention erhält die DLL ein “.Contracts”. Ein Beispiel:

  • UAR.Demo //Implementierung
  • UAR.Demo.Contracts //Kontrakte

So weit wie möglich sind dann in der Implementierung alle Klassen internal oder private. Über einen öffentlichen Installer wird beim Start der Anwendung die Registrierung der angebotenen Kontrakte samt derer Implementierungen im Container vorgenommen.

Da demzufolge keinerlei Referenzen mehr zwischen den Implementierungen bestehen und ich in der oben erwähnten Konsolenanwendung nun nur genau einen Einstiegspunkt habe, der sich die initiale Komponente auflöst und startet, fehlen weitere benötigte Assemblies.

Als ich über Twitter das Castle Team diesbezüglich angesprochen habe, kam folgende Antwort:

it might not be trivial. You can walk the graph, but better option would be to have clean layering so it’s obvious

Leider half mir die Aussage nicht weiter, da ich keinen „clean layering”-Ansatz sehe, der besagtes Problem auflöst. Vielleicht kann mir einer der Leser weiterhelfen?

Als Lösung habe ich mich in das Event der Komponentenerstellung von Castle.Windsor gehängt. Wie dies funktioniert, seht ihr in dem Webcast. An dieser Stelle will ich noch den Code veröffentlichen und um Feedback bitten.

 

 

Extension Methods für IWindsorContainer:

   1: static class CastleWindsorExtensions

   2:     {

   3:         public static IWindsorContainer EnableDependencyTracking(this IWindsorContainer container)

   4:         {

   5:             var containerInfo = new ContainerDependencyTracker();

   6:  

   7:             container

   8:                 .Register(Component.For<ITrackContainerDependencies>()

   9:                 .Instance(containerInfo)

  10:                 .LifestyleSingleton());

  11:  

  12:             container.Kernel.ComponentCreated += containerInfo.AddRequiredAssembly;

  13:  

  14:             return container;

  15:         }

  16:  

  17:         public static IWindsorContainer EnableMemoryDiagnostic(this IWindsorContainer container)

  18:         {

  19:             //have a look at http://docs.castleproject.org/Windsor.Performance-Counters.ashx?HL=lifecycledcomponentsreleasepolicy

  20:             var diagnostic = LifecycledComponentsReleasePolicy

  21:                                 .GetTrackedComponentsDiagnostic(container.Kernel);

  22:             var counter = LifecycledComponentsReleasePolicy

  23:                                 .GetTrackedComponentsPerformanceCounter(new PerformanceMetricsFactory());

  24:             container.Kernel.ReleasePolicy = new LifecycledComponentsReleasePolicy(diagnostic, counter);

  25:  

  26:             return container;

  27:         }

  28:     }

 

Interface für die Tracking Implementierung:

   1: public interface ITrackContainerDependencies

   2: {

   3:     IEnumerable<Assembly> RequiredAssemblies { get; }

   4:  

   5:     int RegisteredComponents { get; set; }

   6:  

   7:     void AddRequiredAssembly(ComponentModel model, object instance);

   8:  

   9:     StringBuilder ResolvedComponentsInARow { get;}

  10: }

 

Implementierung für das Tracking:

   1: class ContainerDependencyTracker : ITrackContainerDependencies

   2: {

   3:     public ContainerDependencyTracker()

   4:     {

   5:         ResolvedComponentsInARow = new StringBuilder();

   6:     }

   7:  

   8:     readonly List<Assembly> _requiredAssemblies = new List<Assembly>();

   9:  

  10:     int Number;

  11:     public StringBuilder ResolvedComponentsInARow

  12:     {

  13:         get;

  14:         private set;

  15:     }

  16:  

  17:     public IEnumerable<Assembly> RequiredAssemblies

  18:     {

  19:         get

  20:         {

  21:             return _requiredAssemblies.Distinct().ToList();

  22:         }

  23:     }

  24:  

  25:     public int RegisteredComponents

  26:     {

  27:         get;

  28:         set;

  29:     }

  30:  

  31:     public void AddRequiredAssembly(ComponentModel model, object instance)

  32:     {

  33:         Number += 1;           

  34:         ResolvedComponentsInARow.AppendLine(string.Format("{0}: {1}", Number, model.Implementation));

  35:  

  36:  

  37:         foreach (var service in model.Services)

  38:             _requiredAssemblies.Add(service.Assembly);

  39:  

  40:         _requiredAssemblies.Add(model.Implementation.Assembly);

  41:     }

  42: }

 

In dem Video gehe ich auch kurz auf die Auffindung von Speicherlecks ein. Die Implementierung ist oben in den Extensions enthalten. Es sei an dieser Stelle auf folgende Seite im Castle Wiki verwiesen.

FakeItEasy und Castle.Core

Es ist vollbracht. Das Team um FakeItEasy hat endlich die Abhängigkeit zu Castle.Core entfernt, indem es selbige mit IL Merge in die eigene DLL gepackt hat. Damit lassen sich Castle und FakeItEasy NuGet Packages separat updaten.

Vorher: image

PM> Install-Package FakeItEasy -Version 1.7.4626.65
Attempting to resolve dependency ‚Castle.Core (≥ 3.1.0.0)‘.
Successfully installed ‚Castle.Core 3.1.0‘.
Successfully installed ‚FakeItEasy 1.7.4626.65‘.
Successfully added ‚Castle.Core 3.1.0‘ to FakeAndCastle.
Successfully added ‚FakeItEasy 1.7.4626.65‘ to FakeAndCastle.

 

Nachher:

image   PM> install-package FakeItEasy
   Successfully installed ‚FakeItEasy 1.10.0‘.
   Successfully added ‚FakeItEasy 1.10.0‘ to FakeAndCastle.

 

 

 

 

Zurückzuführen ist das auf ein großes Interesse seitens der Community. Auf meine Bitte hin wurde in die aktuelle Version 1.10.0 Castle.Core 3.2.0 integriert.

 

Good job, guys!

Entity Framework Webcasts Serie

In den vergangenen Tagen gingen Teil 4 und 5 meiner Entity Framework Webcast Serie online. Außerdem ist geplant in den kommenden Tagen noch Teil 6 zu veröffentlichen. Das liegt darin begründet, dass ich verstärkt per E-Mail adressiert mit der Bitte wurde, die restlichen Teile nachzuschieben. Außerdem erhielt ich mehrfach Anfragen bzgl. diverser Schwerpunkte, die ich in zukünftigen Beiträgen aufgreifen möge. Den Bitten werde ich so weit mir möglich nachkommen.

Deshalb an dieser Stelle nochmal der Hinweis, dass man mich über die üblichen Kommunikationskanäle gerne ansprechen darf. Das ein oder andere Feedback hilft mir auch dabei mich immer wieder aufzurappeln und in der Freizeit derartigen Inhalt zu produzieren.

 

Hier ein kurzer Auszug aus einer Mail, die ich gerade erst vergangene Woche erhalten habe:

Hallo Herr Armbruster,

erstmal kompliment für die 3 m.E. sehr guten Videos. Gerne hätte ich noch mehr bzgl. Entity Framework gesehen. Die Art und Weise wie die Thematik erläutert wird, ist Ihnen sehr gut gelungen.

Schön wäre z.B. noch:

– Genaue Erläuterung der Konfigurationsdatei

– WCF in Verbindung mit EF

– Architekturgestaltung bis hin zur UI

Die Gestaltung und Auslagerung der Queries im Teil3 ist für mich ein riesen Lernfortschritt gewesen. Probleme habe ich jetzt bekommen, als ich die Abfrage, also eine IQuery über einen WCF Dienst laufen lassen wollte. Dieser akzeptiert ja soweit mir bekannt ist, keine generischen Typen.

Können Sie hierzu eine kurze Info geben, wie dies realisiert werden kann?

 

 

Aktuell stehen folgende 5 Webcasts in Full HD Auflösung bereit:

  • Teil 1 – DbContext und POCOS: Wir wechselt man auf den neuen DbContext des Entity Framework 5 und erzeugt sich POCO Objekte frei von jeglichen Technologie-spezifischen Referenzen.
  • Teil 2 – UnitOfWork und IoC: Lose Kopplung ist in diesem Beitrag das Ziel. Der Client verliert vollständig seine Abhängigkeit zum Entity Framework bzw. zur Persistenzschicht.
  • Teil 3 – Queries: Hier zeige ich wie sich ein Query Repository aufbauen und Redundanz vermeiden lässt.
  • Teil 4 – Eigener Kontext: Dieses Video erläutert die Implementierung eines eigenen Kontexts.
  • Teil 5 – Weitere Datenbanken: Der nächste wichtiger Schritt ist das Einbinden weiterer Datenbanken. Der Vorzug hierbei ist die implizite Auflösung des entsprechenden Modells auf Basis von Konventionen.
  • Teil 6 – Stored Procedures und SQL Queries: In Anlehnung an Teil 3 baue ich hier ein entsprechendes Repository für reine SQL Abfragen und Stored Procedures auf.

Der vollständige Quellcode steht in dem Repository ‘MyCleanEntityFramework’ in meinem Github Account zur Verfügung.

Einführung in IoC Container

In diesem Webcast biete ich einen kleinen Einstieg zur Verwendung von IoC Containern. Diese Frameworks helfen bei der Umsetzung des Inversion of Control Principle unter Einsatz von Dependency Injection. Damit ist es möglich gemeinsam an an einem Feature zu arbeiten und so den Work in Progress (WiP) zu minimieren.

  • Alle Blogeinträge zu Castle.Windsor samt den im Video gezeigten Code Beispielen gibt es hier.
  • Die Projekte aus dem Webcast habe ich vorübergehend hier zur Verfügung gestellt.

 

Modularisierung durch Dependency Injection

Webcast Strategy Pattern mit IoC

Den Webcast zu diesem Blogeintrag gibt es hier.

Strategy Pattern mit IoC sauber implementiert

Ein kurzer Hinweis vorab: Den Inhalt des Blogeintrags habe ich auch in einem Webcast zusammengefasst. Das Video gibt es auf YouTube. Den Code findet ihr hier.

In meinem letzten Blogeintrag habe ich das Strategy Pattern in der Praxis gezeigt. Primär gab es noch einen Smell, welchen ich erwähnt hatte: Das Open Closed Principle ist damit noch nicht 100%ig eingehalten und an einer Stelle heble ich mein IoC Konzept aus. Das passiert genau hier:

   1: public StateHandler(IClock clock, IBuildDefaultProposalsValues defaultValues)

   2: {

   3:     Handler = new Dictionary<SelloutStates, ICreateOrderProposal>

   4:               {

   5:                   {SelloutStates.Oversupply, null},

   6:                   {SelloutStates.Predicted, new PredictedGap(defaultValues)},

   7:                   {SelloutStates.Urgent, new UrgentGap(defaultValues, clock)},

   8:                   {SelloutStates.AppointmentWarnings, new AppointmentWarning(defaultValues, clock)},

   9:                   {SelloutStates.Unknown, null},

  10:                   {SelloutStates.Verify, new NoForecastPossible(defaultValues)},

  11:                   {SelloutStates.Ok, new UncomplicatedAppointment(defaultValues, clock)}

  12:               };

  13: }

Zum einen müsste ich die Klasse immer anpassen, wenn ich einen weiteren Status aufnehmen möchte. Zum anderen erzeuge ich mir Instanzen von Klassen, welche ich nicht über den Container erhalten habe, sprich ich hole mir die Abhängigkeiten selbst, statt mir diese gemäß Inversion of Control Principle zuweisen zu lassen. Das wäre zwar möglich gewesen, allerdings würde der Konstruktor dadurch erheblich aufblähen, weil ich pro Status eine Implementierung reinreichen müssten. Dieses Problem könnte ich über Service Location lösen, d.h. ich lasse mir lediglich den Container reinreichen und mache die Auflösung intern. Für mich persönlich auch keine schöne Lösung (Hinweis: Dafür müsste man den Container in sich selbst registrieren…).

Ob nun saubere Dependency Injection mit aufgeblähtem Konstruktor oder Service Location, in jedem Fall bliebe das Problem, dass ich jedes Mal im Container eine weitere Registrierung für einen neuen Status durchführen müsste.

Daraufhin kamen Rückfragen, wie dies am besten zu lösen sei. Das soll Thema dieses Blogeintrags und des dazu passenden Webcasts sein, v.a. weil im Netz auch nur selten saubere Implementierungen anzutreffen sind, die alle Prinzipien einhalten.

Als erstes wird der obere Code gänzlich entfernt, da dieser nicht mehr benötigt wird. Hinter dem Code steckte eigentlich das Factory Pattern. Ich lasse mir durch die Factory (abhängig vom Status) das entsprechende Objekt erzeugen und arbeite dann mit diesem weiter. Castle.Windsor als IoC Container bietet uns hierfür sogenannte interface-based factories an.

Anmerkung: Der folgende Code basiert nicht mehr auf dem bisherigen, welchen ich im vorherigen Blogeintrag verwendet habe. Im Webcast ist dazu alles erläutert und ich habe das Projekt unter Github zur Verfügung gestellt.

   1: yield return Component

   2:     .For<IchVermittleVorschlagsrechner>()

   3:     .AsFactory(c => c.SelectedWith(new VorschlagsrechnerVermittler()));

Wie man sieht, muss man lediglich das Factory-Interface, welches man zuvor selbst ausimplementiert hatte, angeben und im Anschluss ‘AsFactory’ anhängen. Als Parameter übergebe ich den Verweis auf eine Logik, welche die Factory später intern verwendet, um mir das korrekte Objekt (den korrekten Service) zurückzuliefern. Das Bedeutet, dass “new VorschlagsrechnerVermittler” der Factory, wenn auf ihr ein Aufruf stattfindet, sagen muss, was sie zurückgeben soll. Es folgt die Implementierung:

   1: public class VorschlagsrechnerVermittler : DefaultTypedFactoryComponentSelector

   2: {

   3:     protected override string GetComponentName(MethodInfo method, object[] arguments)

   4:     {

   5:         if (method.Name == "Für" && arguments.Length == 1 && arguments[0] is Bestandsstatus)

   6:         {

   7:             var status = arguments[0].ToString();

   8:             //von mir frei gewählte Konvention wie die Komponente im Container heißt

   9:             return string.Format("BerechnerFürArtikelstatus{0}", status);

  10:         }

  11:         return base.GetComponentName(method, arguments);

  12:     }

  13: }

Dieser Code macht nun genau das, was ich vorher explizit im Dictionary definiert habe, allerdings anhand einer Konvention. Die Methode in Zeile 3 liefert als String den Namen der Komponente zurück basieren auf dem Namen des Status, also z.B. ergibt sich für den Status “Ok” der Komponentenname “BerechnerFürArtikelstatusOk”.

Nun fehlt lediglich noch eine kleine Anpassung für den IoC Container. Dieser weiß bisher nichts von einer Komponente “BerechnerFürArtikelstatusOk”. Eine Möglichkeit wäre, dass ich – wie bereits eingangs erwähnt – für jeden Status die Ausprägung im Container registriere, also in diesem Fall beispielsweise so:

   1: yield return Component.For<IchErrechneArtikelZukaufsvorschlag>()

   2:     .ImplementedBy<Ok>()

   3:     .Named("BerechnerFürArtikelstatusOk")

   4:     .LifestyleTransient();

Das widerspricht immer noch dem OCP, sodass ich es wie folgt löse:

   1: yield return AllTypes.FromThisAssembly()

   2:     .BasedOn<IchErrechneArtikelZukaufsvorschlag>()

   3:     .Configure(a => a.Named(string.Format("BerechnerFürArtikelstatus{0}",

   4:         a.Implementation.UnderlyingSystemType.Name)))

   5:     .Configure(a => a.LifestyleTransient());

Zunächst hole ich mir alle Klassen aus der aktuellen Assembly, welche auf “IchErrechneArtikelZukaufsvorschlag” basieren, also alle meinen konkreten Status-Implementierungen. Im Anschluss sage ich noch, welchen Name diese Komponenten im Container bekommen sollen. Hier steht die selbe Konvention wie in dem Code Sample  zuvor. Der Vollständigkeit halber sei erwähnt, dass ich hier gegen das Don’t Repeat Yourself Principle verstoße. Dies soll lediglich der Vereinfachung im Beispiel dienen.

Ab jetzt muss ich, wenn ein weiterer Status hinzu kommt, lediglich eine Implementierung für diesen machen. Bestehender Code muss nicht mehr angefasst werden.

Universal Service Host

Ich habe soeben in meinem Github Repository ein Projekt zur Verfügung gestellt, mit welchem ihr euch sehr einfach NT Dienste basteln könnt. Einfach das Interface “IAmService” aus der Contracts Assembly in eurem Projekt implementieren und mit Castle.Windsor das Ganze im IoC-Container registrieren und schon könnt ihr euer Programm als Dienst bereitstellen. Das geht im Übrigen auch für eine beliebige Anzahl an Diensten, solange die DLLs dazu im gleichen Verzeichnis wie die EXE-Datei liegen.

Hier ein Video, in dem ich alles erkläre:

Entity Framework Webcasts – UnitOfWork und IoC

 

Ich habe auf YouTube mit einer Webcast Reihe zum Entity Framework begonnen. Ich stelle dabei einen Lösungsansatz vor, der zum Ziel hat das EF in der Anwendungsarchitektur als Persistenzschicht derart zu integrieren, dass Unit und Integration Tests einfach zu implementieren sind. Darüber hinaus soll der Ansatz gängige Prinzipien wie Inversion of Control (IoC), Single Responsibility Principle (SRP), Open-Closed-Principle (OCP) umsetzen, sowie die Abhängigkeiten zum Framework minimieren.

In diesem zweiten Teil zeige ich wie man durch den Einsatz eines IoC-Containers eine direkte Abhängigkeit zur Persistenzschicht vermeiden kann. Darüber hinaus setze ich hier bereits das Konzept einer UnitOfWork ein, welche ich in einem folgenden Teil näher erläutern werde.

Quellen:

Castle Windsor – Handy Ruse Part III

In this blog entry I published code for an IoC Initializer. The following container Integration Test tries to create an instance of each registered service that is not of type IAmNotTestable. Definitely an Integration Tests that every application needs!

Integration Test of the container using Machine.Specifications as UnitTesting Framework:

   1: using System;

   2: using System.Diagnostics;

   3: using System.Linq;

   4: using Castle.MicroKernel;

   5: using Castle.Windsor;

   6: using comWORK.Contracts;

   7: using comWORK.Infrastructure.IoC;

   8: using Machine.Specifications;

   9: using Machine.Specifications.Utility;

  10:  

  11: namespace UAR.IntegrationTests

  12: {

  13:     public abstract class ContainerSpecs

  14:     {

  15:         protected static IWindsorContainer CreateContainer()

  16:         {

  17:             return new IoCInitializer()

  18:                     .RegisterComponents()

  19:                     .Container;

  20:         }

  21:     }

  22:  

  23:     [Subject("Container Specs")]

  24:     public class When_the_application_starts_up : ContainerSpecs

  25:     {

  26:         static IHandler[] _handlers;

  27:         static IWindsorContainer _container;

  28:  

  29:         Establish context = () => { _container = CreateContainer(); };

  30:  

  31:         Because of = () => { _handlers = _container.Kernel.GetAssignableHandlers(typeof(object)); };

  32:  

  33:         Cleanup after = () => _container.Dispose();

  34:  

  35:         It should_be_able_to_create_an_instance_of_each_registered_service =

  36:             () => _handlers

  37:                       .Where(

  38:                           handler =>

  39:                           handler.ComponentModel.Implementation.GetInterfaces().Contains(typeof(IAmNotTestable)) == false)

  40:                       .Each(handler => handler.ComponentModel.Services

  41:                                            .Each(service =>

  42:                                            {

  43:                                                Debug.WriteLine(String.Format("{0}: {1}/{2}",

  44:                                                                              handler.ComponentModel.Name,

  45:                                                                              service.Name,

  46:                                                                              handler.ComponentModel.Implementation.Name));

  47:  

  48:                                                if (service.ContainsGenericParameters)

  49:                                                {

  50:                                                    service.GetGenericArguments()

  51:                                                        .Each(argument => argument.GetGenericParameterConstraints()

  52:                                                                              .Each(

  53:                                                                                  constraint =>

  54:                                                                                  _container.Resolve(service.MakeGenericType(constraint))));

  55:                                                }

  56:                                                else

  57:                                                {

  58:                                                    _container.Resolve(service);

  59:                                                }

  60:                                            }));

  61:     }

  62: }

Implementation of IAmNotTestable

   1: public interface IAmNotTestable{}

Notice: I will publish a new version soon that addresses some open problems that i don’t want to mention here.

Castle Windsor – Handy Ruse Part II

In every application you have to initialize the container as part of the bootstrapping process. I moved the bootstrapping logic into a seperate assembly. Here’s the IoC part as fluent API. The code registers all implementations of IWindsorInstaller contained in the folder of the executing assembly. I also have a method “RunStartupConfiguration” that executes the start-method of all components which implement the interface. This could be useful for configuration reason for example.

Implementation of IoCInitializer

   1: public class IoCInitializer : IDisposable

   2: {

   3:     public IWindsorContainer Container { get; private set; }

   4:  

   5:     public IoCInitializer()

   6:     {

   7:         Container = new WindsorContainer();

   8:     }

   9:  

  10:     public void Dispose()

  11:     {

  12:         if (Container != null)

  13:         {

  14:             Container.Dispose();

  15:             Container = null;

  16:         }

  17:     }

  18:  

  19:     public IoCInitializer RegisterComponents()

  20:     {

  21:         var appDomainDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);

  22:         var foundAssemblies = FromAssembly.InDirectory(new AssemblyFilter(appDomainDirectory));

  23:  

  24:         Container.Install(foundAssemblies);

  25:  

  26:         return this;

  27:     }

  28:  

  29:     public IoCInitializer RunStartupConfiguration()

  30:     {

  31:         Container

  32:             .ResolveAll<IStartupTask>()

  33:             .ToList()

  34:             .ForEach(x => x.Start());

  35:         return this;

  36:     }

  37: }

 

Implementation of IStartupTask:

   1: public interface IStartupTask

   2: {

   3:     void Start();

   4: }

 

You can call this in your bootstrapping logic this way:

   1: Container = new IoC.IoCInitializer()

   2:     .RegisterComponents()

   3:     .RunStartupConfiguration()

   4:     .Container;

 

Be careful, the container and class modifiers are public! Instead you should make it internal and integrate it into the assembly that is responsible for bootstrapping.

Castle Windsor – Handy Ruse Part I

Today I want to share some implementations that I use every once in a while:

Scenario 1: You have an assembly that contains all WinForm controls or perhaps ViewModel classes instead. You don’t want to adapt your installer again and again, if you create new controls respectively new ViewModels.

The following snippet shows an Installer that registers all ViewModels in a WPF assembly of mine. Of course I need to decorate my ViewModels with an special interface, in this case IAmViewModel:

   1: public class Installer : IWindsorInstaller

   2: {

   3:     public void Install(IWindsorContainer container, IConfigurationStore store)

   4:     {

   5:         container.Register(Components().ToArray());

   6:     }

   7:  

   8:     private static IEnumerable<IRegistration> Components()

   9:     {

  10:         yield return Classes.FromThisAssembly()

  11:             .BasedOn<IAmViewModel>()

  12:             .WithServiceSelf()

  13:             .LifestyleTransient();

  14:     }

  15: }

You can afford the same for WinForms. You don’t even have to create an interface:

   1: private static IEnumerable<IRegistration> Components()

   2: {

   3:     yield return Classes.FromThisAssembly()

   4:         .BasedOn<Form>()

   5:         .WithServiceSelf()

   6:         .LifestyleTransient();

   7: }

 

In some little (!) cases it can be useful to inject the container itself into an object. For that reason you can register the container in itself:

   1: Container.Register(

   2:     Component.For<IWindsorContainer>().Instance(Container)

   3: );

Castle Windsor – Forwarding

As I just noticed, since v3.0 there is a new useful possibility for registering multiple services by one component. Take a look at this page.

   1: Component.For<IFoo, IBar>().ImplementedBy<FooBar>();

You want a sample?

   1: yield return Component

   2:     .For<ICalculateOrderProposals, IShowOrderProposals>()

   3:     .ImplementedBy<ArticleOrderProposals>()

   4:     .LifestyleSingleton();

I wanted to seperate the concerns “calculate order proposals” and “show order proposals” in two interfaces in order have more transparency and directness in the consuming components. But because of cohesion i wanted to implement this in one class.

Nice work guys!

Inversion of Control and Entity Framework

Today i want to show you my approach to resolve the requested entity framework object context at runtime. Starting point:

  • First, i want to have just one implementation of an IUnitOfWork to resolve any kind of repository like Repository<Order>
  • Second, my unit of work should autodiscover the proper context for my requested type of domain model as i have different databases and object contexts. For example, Order is a domain object of my domain model (namespace Domain.ComWork) according to the context ‘comwork’, which is mapping to the database ‘comwork’. There’s another domain object like Customer in my domain model (namespace Domain.MyHeco) according to the context ‘myheco’, which is mapping to the database ‘myheco’.

So how can i achieve this? I will use an IoC container like Castle.Windsor. You can add it to your Visual Studio project by the nuget command “install-package Castle.Windsor”. I want to mention that this scenario needs a little bit of advanced IoC techniques because the dependent component has to be resolved at runtime. So you’re not able to register a dedicated component for an interface. Instead you’ve got to use a facility. Allright, so we tell the container that we will register a facility:

   1: container.AddFacility<TypedFactoryFacility>();

 

In line 1 we tell the container that it has to load the necessary infrastructure for facilities. Let’s take a look at the registration process. Here’s my method that will return me an IEnumerable of IRegistration.

   1: static IEnumerable<IRegistration> Components()

   2: {

   3:     yield return Component

   4:         .For<IContextFactory>()

   5:         .AsFactory(c => c.SelectedWith<ContextFactoryHandlerSelector>());

   6:     yield return Component

   7:         .For<ContextFactoryHandlerSelector>();

   8:     yield return Component

   9:         .For<IUnitOfWork>()

  10:         .ImplementedBy<UnitOfWork>();

  11:     yield return Component

  12:       .For<ComWorkContext>()

  13:       .Named("comworkcontext");

  14:     yield return Component

  15:       .For<MyHecoContext>()

  16:       .Named("myhecocontext");

  17: }

 

Here’s the good news: Castle Windsor has an out of the box feature that creates you the needed factory. In other words: The container creates automatically the factory. You’re code is unaware of the container. Take a look at this article. If you want to use this you’ve have to follow some conventions. In my approach i decided to develop my own implementation to follow my own convetions. Take a look at line 5.  With “.AsFactory” i tell the container that i don’t register a concrete implementation for that service (IContextFactory). If i would follow the conventions of Castle.Windsor calling AsFactory() would be enough.

Here’s the code for my own implementation of a TypedFactoryComponentSelector (this would be auto generated by using just AsFactory without parameters):

   1: public class ContextFactoryHandlerSelector : ITypedFactoryComponentSelector

   2: {

   3:     public TypedFactoryComponent SelectComponent(MethodInfo method, 

   4:         Type type, object[] arguments)

   5:     {

   6:         var requestFor = method.GetGenericArguments().First();

   7:         

   8:         var @namespace = string.Format("{0}context", 

   9:             requestFor.Namespace.ToLower()

  10:             .Replace("domain.",""));

  11:         

  12:         return new TypedFactoryComponent(@namespace, method.ReturnType, null);

  13:     }

  14: }

 

My convention is pretty simple: The name of my object context is the same as the namespace of my model without the string “domain.” and with “context” appended.

Sample: Full name of my domain object: “domain.comwork.order”

  • use just the namespace –> domain.comwork
  • replace domain –> comwork
  • add context –> comworkcontext

I have two kind of domain models (domain.comwork and domain.myheco) so i need two contexts (comworkcontext and myhecocontext). Every context is registered:

   1: yield return Component

   2:   .For<ComWorkContext>()

   3:   .Named("comworkcontext");

   4: yield return Component

   5:   .For<MyHecoContext>()

   6:   .Named("myhecocontext");

 

Now we’ve got it: We have a facility that invokes a call to my self implemented factory if a service (defined in the interface IContextFactory) is requested. The factory returns the name of the needed context at runtime. My Interface looks like this:

   1: public interface IContextFactory

   2: {

   3:     ObjectContext GetContextFor<T>();

   4: }

And here’s the generic part. If i call GetContextFor<domain.comwork.order> i will get my comworkcontext. If i call GetContextFor<domain.myheco.customer> i will get my myhecocontext.

The last step is to inject the factory in my UnitOfWork. Nothing easier than that:

   1: public class UnitOfWork : IUnitOfWork

   2: {

   3:     private readonly IContextFactory _factory;

   4:  

   5:     public UnitOfWork(IContextFactory factory)

   6:     {

   7:         _factory = factory;

   8:     }

   9:  

  10:     //here you would return an IRepository<T>

  11:     //this is just a sample code

  12:     public void GetRepository<T>() where T : class 

  13:     {

  14:         Console.WriteLine(_factory.GetContextFor<T>().GetContextName());

  15:     }

  16: }

 

And how can i resolve my concrete UnitOfWork in my program?

   1: static class Program

   2: {

   3:     static void Main(string[] args)

   4:     {

   5:             using (var container = new WindsorContainer())

   6:             {

   7:                 container.AddFacility<TypedFactoryFacility>();

   8:                 container.Register(Components().ToArray());

   9:  

10: container.Resolve<IUnitOfWork>()

.GetRepository<Domain.ComWork.Foo>();

11: container.Resolve<IUnitOfWork>()

.GetRepository<Domain.MyHeco.Bar>();

  12:             }

  13:     }

  14:  

  15:     static IEnumerable<IRegistration> Components()

  16:     {

  17:         //Registrations...

  18:     }

  19: }

%d Bloggern gefällt das: