Project DescriptionA generic, flexible, static factory written in C# contained in a single file for easy inclusion in any project.
You'll never have to write another factory again. The main points of extensibility are exposed so you can control it's behavior without writing boilerplate code.
This file is available as a nuget package (package id: genericfactory) and can be easily included or in your project.
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 ...
}
}