fredag, maj 02, 2008

Plugin-pattern på webben

Martin Fowler har i sin bok Patterns of Enterprise Application Architecture beskrivit ett plugin patter som man kan använda för att länka ihop applikationer genom konfiguration istället för vid kompilering. Min tanke var att bygga en webbapplikation, typ en portal, som sedan blir medveten om att andra applikationer existerar bara genom en konfigurering istället för att man måste känna till den vid utveckling. Min vision var att kunna utveckla och uppgradera portalen för sig och sedan utveckla och uppgradera applikationer för sig.

Jag började med att definiera ett interface som varje applikation måste implementera. Det interfacet ska kunna leverera information om applikationen i fråga:

    public interface IApplicationInfo

    {

        string ApplicationName { get; set; }

    }

 

Sedan la jag till en PluginFactory med en statisk metod getPlugin. Den metodens uppgift var att läsa in assemblyt (snyggt ord) från disk och skapa en instans av den klass som implementerar IApplicationInfo och returnera denna...

public static IApplicationInfo getPlugin(string assemblyName)

{

var assembly = Assembly.LoadFrom(assemblyName);

var assemblyTypes = from a in assembly.GetTypes()

                    select a;

 

foreach (var t in assemblyTypes)

{

    var o = Activator.CreateInstance(t);

    if (o is IApplicationInfo)

        return o as IApplicationInfo;

}

return null;

}

 

Först placerade jag min PluginFactory i samma Visual Studio 2008 projekt som Portalen men det gjorde att mina enhetstester mot getPlugin blev otroligt sega att köra eftersom att den måste starta igång webservern först. Det blev dock betydligt bättre när jag flyttade ut den till ett eget class-library. Ett härligt bevis på hur test-driven utveckling gör att man fattar beslut tidigt som gör att ens arkitektur blir mer testbar!

Nästa steg var att lägga till en AppSetting i min web.config för varje applikation som jag vill att portalen ska känna till och använde mig av en LINQ-fråga för att hämta ut dessa:

var applications = from a in ConfigurationManager.AppSettings.AllKeys

                   where a.StartsWith("PortalApplication")

                   select new { AssemblyName = ConfigurationManager.AppSettings[a] };

 

Grymt coolt! Refelction, LINQ, plugin-patterns och allt möjligt coolt men sen då? Vad har jag vunnit med det här jämfört med att bara lägga in den här informationen i web.config eller i en databas. Hur ska jag nu få mina applikationer att agera i portalen som om de var en del av portalen från första början?

Ju mer jag funderar på det hela desto mer ser det ut som att det är Facebook jag vill bygga (fast utan den sociala delen)... För det är ju precis det Facebook är, en portal med viss gemensam funktionalitet och ett antal tjänster som sedan applikationsutvecklare kan nyttja för att bygga egna applikationer som jackas in i portalen. Så hur har Facebook löst interaktionen mellan en applikation och portalen? Kör varje applikation i en IFrame eller? Är det någon som vet??

Inga kommentarer: