1、配置文件与反射技术
使用硬编码方式创建一个对象,必然会带来对象之间的具体依赖。一种最简单的方式是将反射技术与配置文件相结合,在具体对象拥有共同抽象的前提下,通过配置文件获得具体对象的类型信息,然后利用反射创建相应的对象。例如,在领域对象Order类中,可以如此实现:
public class Order
{
private static readonly IOrderStrategy orderInsertStrategy =
LoadInsertStrategy();
private static IOrderStrategy LoadInsertStrategy()
{
//通过配置文件找到具体的订单策略对象
string path = ConfigurationManager.AppSettings["OrderStrategyAssembly"];
string className = ConfigurationManager.AppSettings["OrderStrategyClass"];
//通过反射创建对象实例
return (IOrderStrategy)Assembly.Load(path).CreateInstance(className);
}
}
{
private static readonly IOrderStrategy orderInsertStrategy =
LoadInsertStrategy();
private static IOrderStrategy LoadInsertStrategy()
{
//通过配置文件找到具体的订单策略对象
string path = ConfigurationManager.AppSettings["OrderStrategyAssembly"];
string className = ConfigurationManager.AppSettings["OrderStrategyClass"];
//通过反射创建对象实例
return (IOrderStrategy)Assembly.Load(path).CreateInstance(className);
}
}
在配置文件web.config中,配置如下的节:
<add key="OrderStrategyAssembly" value="AgileDon.BLL"/>
<add key="OrderStrategyClass" value="BLL.OrderSynchronous"/>
<add key="OrderStrategyClass" value="BLL.OrderSynchronous"/>
通过引入泛型,我们可以对前面的逻辑进行有效的封装,例如定义如下的工厂辅助类。
public static class FactoryHelper<T>
where T:class
{
private static T instance = null;
public static T Create(string typeNameKey,
string nameSpace,
string assemblyPath)
{
if (instance == null)
{
string typeName = ConfigurationManager.AppSettings[typeNameKey];
string className = nameSpace + "." + typeName;
instance = (T)Assembly.Load(assemblyPath).
CreateInstance(className);
}
return instance;
}
}
where T:class
{
private static T instance = null;
public static T Create(string typeNameKey,
string nameSpace,
string assemblyPath)
{
if (instance == null)
{
string typeName = ConfigurationManager.AppSettings[typeNameKey];
string className = nameSpace + "." + typeName;
instance = (T)Assembly.Load(assemblyPath).
CreateInstance(className);
}
return instance;
}
}
注意, Create()辅助方法中的typeNameKey,是指向具体对象类型的键值。通常建议将其键值赋值为具体对象类型的抽象接口类型名,而对应的值则是目标创建对象的类型名。例如:
<add key="IOrderStrategy" value="OrderSynchronous"/>
public static class BLLFactory<T>
where T:class
{
public static T Create(string typeNameKey)
{
string nameSpace = ConfigurationManager.AppSettings["BLLAssembly"];
string assemblyPath = ConfigurationManager.AppSettings["BLLPath"];
return BaseFactory<T>.CreateT(
typeNameKey, nameSpace, assemblyPath);
}
}
where T:class
{
public static T Create(string typeNameKey)
{
string nameSpace = ConfigurationManager.AppSettings["BLLAssembly"];
string assemblyPath = ConfigurationManager.AppSettings["BLLPath"];
return BaseFactory<T>.CreateT(
typeNameKey, nameSpace, assemblyPath);
}
}
针对订单策略对象,对应的配置文件为:
<add key="BLLAssembly" value="AgileDon.BLL"/>
<add key="BLLPath" value="AgileDon.BLL"/>
<add key="IOrderStrategy" value="OrderSynchronous"/>
<add key="BLLPath" value="AgileDon.BLL"/>
<add key="IOrderStrategy" value="OrderSynchronous"/>
IOrderStrategy orderInsertStrategy = BLLFactory<IOrderStrategy>.Create(
"IOrderStrategy");
"IOrderStrategy");
如果需要将订单插入策略从同步修改为异步方式,只需将配置文件中IOrderStrategy键对应的值修改为"OrderAsynchronous"即可。