Created
October 15, 2010 23:26
-
-
Save spearson/629145 to your computer and use it in GitHub Desktop.
Use one implementation for all those pointless factories!
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment