public
Last active

Use one implementation for all those pointless factories!

  • Download Gist
RedundantFactories.cs
C#
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
namespace xofz.Playground.Tests
{
using System;
using Xunit;
 
public class RedundantFactories
{
[Fact]
public void Are_used_like_this()
{
var stringFactory = new RedundantFactory<string>();
 
var s = stringFactory.Create('x', 15);
Console.WriteLine(s);
 
var subString = s.Substring(3, 7);
Console.WriteLine(subString);
}
 
[Fact]
public void Are_also_used_like_this()
{
var randomFactory = new RedundantFactory<Random>();
var random = randomFactory.Create();
Console.WriteLine(random.NextDouble());
}
 
[Fact]
public void Can_be_used_without_generics()
{
var stringFactory = new RedundantFactory(typeof(string));
 
var s = stringFactory.Create('x', 12);
Console.WriteLine(s);
 
var subString = s.Substring(3, 7); // check out that dynamic typing! w00t w00t C# 4.0!!
Console.WriteLine(subString);
}
}
}
RedundantFactory.cs
C#
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
namespace xofz.Playground
{
using System;
using System.Collections.Generic;
using System.Linq;
 
public class RedundantFactory<T> : RedundantFactory
{
public RedundantFactory()
: base(typeof(T))
{
}
 
public new T Create(params dynamic[] args)
{
return (T)base.Create(args);
}
}
 
public class RedundantFactory
{
public RedundantFactory(Type typeToCreate)
{
if (typeToCreate.IsAbstract || typeToCreate.IsInterface)
{
throw new ArgumentException("Type to create must be concrete");
}
 
this.typeToCreate = typeToCreate;
var constructors = typeToCreate.GetConstructors();
var paramSets =
constructors.Select(
constructor => constructor.GetParameters()
.Select(parameter => parameter.ParameterType)
.ToArray());
 
this.parameterSets = paramSets;
}
 
public dynamic Create(params dynamic[] args)
{
var parameterSetsWithCorrectLength = this.parameterSets.Where(parameters => parameters.Length == args.Length);
if (!parameterSetsWithCorrectLength.Any())
{
throw new ArgumentException(@"Too many or too few args", "args");
}
 
Type[] correctParameterSet = null;
foreach (var parameterSet in parameterSetsWithCorrectLength)
{
var parameterSetIsCorrect = true;
 
for (var i = 0; i < args.Length; ++i)
{
if (args[i].GetType() != parameterSet[i])
{
parameterSetIsCorrect = false;
}
}
 
if (!parameterSetIsCorrect)
{
continue;
}
 
correctParameterSet = parameterSet;
}
 
if (correctParameterSet == null)
{
throw new ArgumentException(@"No matching ctor could be found for args", "args");
}
 
return Activator.CreateInstance(this.typeToCreate, args);
}
 
private readonly Type typeToCreate;
private readonly IEnumerable<Type[]> parameterSets;
}
}

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.