Could I use the Factory Pattern in this scenario?
I was wondering if I could - and how - I could use the Factory Pattern in this scena开发者_运维问答rio?
I have a the following classes...
public interface IStub<T> where T : class
{
IEnumerable<T> CreateStubs();
}
public FooStub : IStub<Foo>
{
public IEnumerable<Foo> CreateStubs() { ... }
}
public BarStub : IStub<Bar>
{
public IEnumerable<Bar> CreateStubs() { ... }
}
.. etc ...
and I was wondering if it's possible to create the instances through a factory method like ...
// This ends up returning an enumerable of Stubs.
var stubs = StubsFactory.CreateStubs<Foo>();
Is this possible / am I on the right track, here?
Like this. Modify the Type.GetType line if the implementation and stub isnt in the same assembly or namespace.
class UberCoolFactory
{
public static T CreateStubs<T>()
{
string ns = typeof(T).Namespace;
string name = typeof(T).Name;
string assembly = typeof(T).Assembly.GetName().Name;
Type type = Type.GetType(string.Format("{0}.{1}Stub, {2}", ns, name, assembly));
return (T)Activator.CreateInstance(type);
}
}
Alternative:
class FactoryTwo
{
/// <summary>
/// Search through all loaded assemblies that exists in the current directory.
/// </summary>
/// <typeparam name="T"></typeparam>
public static T CreateStub<T>() where T : class
{
string currentDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
string wantedTypeName = typeof(T).Name + "Stub";
List<Type> foundTypes = new List<Type>();
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
{
if (!currentDir.Equals(Path.GetDirectoryName(assembly.Location)))
continue;
foreach (var type in assembly.GetTypes())
{
if (!type.Name.Equals(wantedTypeName))
continue;
foundTypes.Add(type);
}
}
if (!foundTypes.Any())
return null;
if (foundTypes.Count > 2)
throw new AmbiguousMatchException("Found multiple stubs implementing '" + typeof(T).FullName + "'.");
return (T) Activator.CreateInstance(foundTypes[0]);
}
}
Usage:
var instance = UberCoolFactory.CreateStubs<Foo>();
var instance2 = FactoryTwo.CreateStub<Foo>();
Extending jgauffin's answer about searching a target type:
string targetType = "BlahStub";
IEnumerable<Type> result =
from assembly in AppDomain.CurrentDomain.GetAssemblies()
where !String.Equals(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), assembly.Location, StringComparison.OrdinalIgnoreCase)
from type in assembly.GetTypes()
where String.Equals(type.Name, targetType, StringComparison.OrdinalIgnoreCase)
select type;
Factory declaration:
static class StubsFactory<TStub, TClass>
where TStub : IStub<TClass>
where TClass : class
{
public static IEnumerable<TClass> CreateStubs()
{
return ((TStub)Activator.CreateInstance<TStub>()).CreateStubs();
}
}
Usage:
IEnumerable<Foo> q = StubsFactory<FooStub, Foo>.CreateStubs();
Is it what you're looking for?
精彩评论