Strategie di caricamento dei provider

In "L'evoluzione nel disegno di architetture ..." avevo detto che il mio - ma non solo - disegno di archietture va verso l'uso del Provider Model...

Definiamo un provider e la sua factory.

    interface IProvider
    {
        void HelloWorld();
    }
 
    interface IProviderFactory
    {
        IProvider CreateIstance();
    }

Diamo un implementazione al provider e alla sua factory

 
    class ProviderImpl: IProvider
    {
        public void HelloWorld()
        {
            System.Console.WriteLine("Hello World!");
        }        
    }
    class ProviderImplFactory: IProviderFactory  
    {
        public IProvider CreateIstance()
        {
            return new ProviderImpl();
        }
    }

Detto che l'uso della factory per me rimane sempre un "must" in certe situazioni... Quali strategie abbiamo per caricare il provider nella nostra Facade e/o Manager che dir si voglia?

1. Caricamento statico. Consigliato se non c'è tempo, non si ha voglia di pensare ad una strategia ma si vuole comunque iniziare ad impostare una struttura a provider. Ovviamente c'è una dipendenza forte tra Facade e provider concreto.

    static class FacadeWithStaticProvider
    {
        private static readonly IProvider provider;
        static FacadeWithStaticProvider()
        {
            provider = new ProviderImplFactory().CreateIstance();
        }
        public static void HelloWorld()
        {
            provider.HelloWorld();
        }
    }

2. Caricamento a PluIn. E' quello decisamente più aperto e che da meno vincoli di dipendenza tra Facade e Provider concreto. Occorre definire una strategia di configurazione dove leggere qual'è il nome della factory da usare.

    class FacadeWithPlugInProvider
    {
        private static IProvider provider;
        private static IProvider Provider
        {
            get
            {
                if (provider == null)
                {
                    //TODO: Leggere Nome del factory/provider dal sistema di configurazione applicazione.
                    string factoryTypeName = "MarcoBarzaghi.Studio.ProviderLab.ProviderImplFactory";
                    Type factoryType = Type.GetType(factoryTypeName);
                    IProviderFactory factory = (IProviderFactory)Activator.CreateInstance(factoryType);
                    provider = factory.CreateIstance();  
                }
                return provider;
            }
        }
        
        public static void HelloWorld()
        {
            Provider.HelloWorld();
        }
    }

3. Caricamento tramite sola registrazione. In questa strategia il consumer della Facade registra staticamente il provider che la Facade dovrà usare. Non so a chi lo consiglio perchè un provider così fatto lo considerò troppo limiato/limitante ma ottimo nella teoria per meglio capire/approcciare la strategia del punto (4).

    class FacadeWithRegisteredProvider
    {
        private static IProvider provider;
        public static void RegisterProvider(IProvider p)
        {
            provider = p;
        }
        private static IProvider Provider
        {
            get
            {
                if (provider == null)
                    throw new NullReferenceException("Provider not registerd.");
                return provider;
            }
        }
        public static void HelloWorld()
        {
            Provider.HelloWorld();
        }
    }

4. Un caricamento Mixed tra il (2) a PlugIn e il (3) tramite registrazione mi sembra quello più interessante. Questa modalità offre tutti i vantaggi del PlugIn legati alla semplice intercabialibità dei Provider ma non sono da sottivalutare le potenzialità che si hanno nel poter registrare dall'alto i provider anche se staticamente. E' utile nella fase testing dove nel classico metodo di inizializzazione/startup del tester si può registrare staticamente il Mock Provider che si vuole usare senza dover introdurre problematiche di configurazione o errori legati ad essa. Può essere inoltre utile quando si hanno sistemi già pronti per essere pluggabili ma non si vuole che committente ne possa sfruttare tali potenzialità per cui all'avvio dell'applicazione ("Application_Start" per il web e nel "Main" per le win) possiamo vincolare staticamente i provider da usare (ovviamente la cosa porta vantaggi e svantaggi).

    class FacadeWithMixedProviderLoading
    {
        private static IProvider provider;
        public static void RegisterProvider(IProvider p)
        {
            provider = p;
        }
        private static IProvider Provider
        {
            get
            {
                if (provider == null)
                {
                    //TODO: Leggere Nome del factory/provider dal sistema di configurazione applicazione.
                    string factoryTypeName = "MarcoBarzaghi.Studio.ProviderLab.ProviderImplFactory";
                    Type factoryType = Type.GetType(factoryTypeName);
                    IProviderFactory factory = (IProviderFactory)Activator.CreateInstance(factoryType);
                    provider = factory.CreateIstance();
                }                
                return provider;
            }
        }
        public static void HelloWorld()
        {
            Provider.HelloWorld();
        }
    }

Ops... avevo dimenticato 2 righe di esempio!

 Console.WriteLine("FacadeWithStaticProvider ...");
 FacadeWithStaticProvider.HelloWorld();
 Console.WriteLine("FacadeWithPlugInProvider ...");
 FacadeWithPlugInProvider.HelloWorld();
 Console.WriteLine("FacadeWithRegisteredProvider ...");
 FacadeWithRegisteredProvider.RegisterProvider(new ProviderImplFactory().CreateIstance());
 FacadeWithRegisteredProvider.HelloWorld();
 Console.WriteLine("FacadeWithMixedProviderLoading ...");
 //Questa chimata è opzionale e dipende dal contesto d'uso ...
 //FacadeWithMixedProviderLoading.RegisterProvider(new ProviderImplFactory().CreateIstance());
 FacadeWithMixedProviderLoading.HelloWorld();

posted @ venerdì 4 agosto 2006 15:32

Print
Comments have been closed on this topic.
«dicembre»
domlunmarmergiovensab
24252627282930
1234567
891011121314
15161718192021
22232425262728
2930311234