Factory based on attributes
    class Program
    {
        public class Data
        {
            public byte[] RawData { get; set; }
        }

        [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
        public sealed class ExtensionAttribute: Attribute
        {
            public ExtensionAttribute(string extension)
            {
                Extension = extension;
            }

            public string Extension { get; private set; }
        }
        
        public abstract class LoaderBase
        {
            public abstract Data Load(string filename);
        }

        [Extension(".fmt1")]
        [Extension(".format1")]
        public sealed class Format1Loader: LoaderBase
        {
            public override Data Load(string filename)
            {
                return new Data { RawData = new byte[10] };
            }
        }

        [Extension(".format2")]
        public sealed class Format2Loader: LoaderBase
        {
            public override Data Load(string filename)
            {
                return new Data { RawData = new byte[25] };
            }
        }
        
        static void Main(string[] args)
        {
            // Registration/discovery (typically performed in a static constructor or application startup/plugin refresh)
            Factory<string, LoaderBase>.Discover(typeof(Program).GetNestedTypes(), type => from ExtensionAttribute attr in type.GetCustomAttributes(typeof(ExtensionAttribute), false)
                                                                                           select attr.Extension);

            // More code here ...

            // Create a loader
            var filename = "testfilename.fmt1";
            var data = Factory<string, LoaderBase>.CreateForExactMatch(Path.GetExtension(filename)).Load(filename);

            // More code here ...

        }
    }

Factory based on version/comparable keys
    class Program
    {
        public interface IProtocol
        {
            void Talk();
        }
        
        public const int V1_MagicWord = 0x23a;
        public class Protocol_V1: IProtocol
        {
            public virtual void Talk()
            {
                // Do stuff here ...
            }
        }

        public const int V2_MagicWord = 0x23b;
        public class Protocol_V2: Protocol_V1
        {
            public override void Talk()
            {
                // Do V2 stuff here ...
            }
        }
        
        static void Main(string[] args)
        {
            // Registration/discovery (typically performed in a static constructor or application startup/plugin refresh)
            Factory<int, IProtocol>.Register<Protocol_V1>(V1_MagicWord);
            Factory<int, IProtocol>.Register<Protocol_V2>(V2_MagicWord);

            // More code here ...

            var clientMagicWord = V1_MagicWord;
            var serverMagicWord = V2_MagicWord;
            var protocol = Factory<int, IProtocol>.CreateForLastKeyLessThanOrEqualTo(Math.Min(clientMagicWord, serverMagicWord));
            protocol.Talk();

            // More code here ...

        }
    }

Last edited Jan 5, 2012 at 9:32 PM by ananth, version 1

Comments

No comments yet.