c#典型工厂化实现实例
工厂接口定义
/// <summary>
/// 工厂接口定义
/// </summary>
/// <remarks>
/// ttarget : abstract product type
/// tsource: concrete product type
/// </remarks>
public interface ifactory
{
#region config and register type mapping
/// <summary>
/// 如果需要同时加载配置文件中定义的映射关系,可以按照srp的原则定义独立的配置类型。
/// 由该配置类型调用这两个接口为factory加载配置信息
/// </summary>
ifactory registertype<ttarget, tsource>(); // fluent interface
ifactory registertype<ttarget, tsource>(string name); // fluent interface
#endregion
#region factory method
ttarget create<ttarget>();
ttarget create<ttarget>(string name);
#endregion
}
注册类
public sealed class typeregistry
{
readonly string defaultnmae = guid.newguid().tostring();
idictionary<type, idictionary<string, type>> registry = new dictionary<type, idictionary<string, type>>();
public void registertype(type targettype,type sourcetype)
{
registertype(targettype, sourcetype, defaultnmae);
}
public void registertype(type targettype, type sourcetype,string name)
{
if (targettype == null) throw new argumentnullexception("targettype");
if (sourcetype == null) throw new argumentnullexception("sourcetype");
if (string.isnullorempty(name)) throw new argumentnullexception("name");
idictionary<string, type> subdictionary;
if (!registry.trygetvalue(targettype, out subdictionary))
{
subdictionary = new dictionary<string, type>();
subdictionary.add(name, sourcetype);
registry.add(targettype, subdictionary);
}
else
{
if (subdictionary.containskey(name))
throw new duplicatekeyexception(name);
subdictionary.add(name, sourcetype);
}
}
public type this[type targettype, string name]
{
get
{
if (targettype == null) throw new argumentnullexception("targettype");
if (string.isnullorempty(name)) throw new argumentnullexception("name");
if (registry.count() == 0)
return null;
return (registry
.where(x => x.key == targettype)).firstordefault().value
.where(x => string.equals(name, x.key))
.firstordefault().value;
}
}
public type this[type targettype]
{
get { return this[targettype, defaultnmae]; }
}
}
工厂类
public class factory : ifactory
{
protected typeregistry registry = new typeregistry();
#region ifactory members
public ifactory registertype<ttarget, tsource>()
{
registry.registertype(typeof(ttarget), typeof(tsource));
return this;
}
public ifactory registertype<ttarget, tsource>(string name)
{
registry.registertype(typeof(ttarget), typeof(tsource), name);
return this;
}
public ttarget create<ttarget>()
{
return (ttarget)activator.createinstance(registry[typeof(ttarget)]);
}
public ttarget create<ttarget>(string name)
{
return (ttarget)activator.createinstance(registry[typeof(ttarget), name]);
}
#endregion
}
调用
[testmethod]
public void createinstance()
{
var factory = new factory()
.registertype<ifruit, apple>()
.registertype<ifruit, orange>("o")
.registertype<ivehicle, bicycle>()
.registertype<ivehicle, bicycle>("a")
.registertype<ivehicle, train>("b")
.registertype<ivehicle, car>("c");
assert.isinstanceoftype(factory.create<ifruit>(), typeof(apple));
assert.isinstanceoftype(factory.create<ifruit>("o"), typeof (orange));
assert.isinstanceoftype(factory.create<ivehicle>(), typeof(bicycle));
assert.isinstanceoftype(factory.create<ivehicle>("a"), typeof(bicycle));
assert.isinstanceoftype(factory.create<ivehicle>("b"), typeof(train));
assert.isinstanceoftype(factory.create<ivehicle>("c"), typeof(car));
}
其实精髓还是在于注册类的一个类似assembly的功能,通过字典的方式,封装,然后通过泛型来比对实现,或者通过配置文件传参数过来实现出一个新的实例化
里面注意连贯接口,泛型,等操作