TranContext是一个比较重要的类,在这个类中,使用了反射方法,实现了根据配置文件动态创建类,实现了接口的作用.
2 {
3 public ConfigurationFactory()
4 {
5 //
6 // TODO: 在此处添加构造函数逻辑
7 //
8 }
9 public static object CreateObject(object context,Type type)
10 {
11 ArgumentValidation.CheckForNullReference (context,"TranContext");
12 ArgumentValidation.CheckForNullReference (type,"Type");
13 ConstructorInfo constructor = type.GetConstructor(new Type[] {context.GetType ()});
14 if (constructor == null)
15 {
16 //throw new Exception(SR.ExceptionProviderMissingConstructor(type.FullName));
17 }
18 object createdObject = null;
19 try
20 {
21 createdObject = constructor.Invoke(new object[]{context});
22 }
23 catch
24 {
25 // Console.WriteLine(ex.Message );
26 // throw new Exception ("create oject: "+type.FullName+" failed!");
27 throw;
28 }
29 return createdObject;
30 }
31 public static object CreateObject(object context,string typeName)
32 {
33 ArgumentValidation.CheckForNullReference (context,"TranContext");
34 ArgumentValidation.CheckForEmptyString(typeName,"typeName");
35 object createObject=null;
36 try
37 {
38 Assembly _Assembly=Assembly.Load(Assembly.GetExecutingAssembly().FullName);
39 createObject=_Assembly.CreateInstance(typeName,
40 true,
41 System.Reflection.BindingFlags.CreateInstance,
42 null,
43 new object[]{context},//args
44 null,//CultureInfo
45 null);
46 }
47 catch
48 {
49 // Console.WriteLine (ex.Message);
50 // throw new Exception ("create oject: "+typeName+" failed!");
51 throw;
52 }
53 return createObject;
54 }
55 }
这两个方法,实现了相同的目标,创建了一个对象,所不同的是实现的方法不同,第一个方法需要一个指定的类型作为参数,创建的对象所指定的类型,它使用了.net中ConstructorInfo这个类来实现的.
ConstructorInfo constructor = type.GetConstructor(new Type[] {context.GetType ()});
createdObject = constructor.Invoke(new object[]{context});
第一句创建了各个构造器,第二句则创建了这个对象. Invoke里的参数是创建的对象的构造函数所要的参数
第二个方法,不需要创建对象的类型,而只需要对象的名称就可以了.在这个方法中使用的是Assembly这个类.
Assembly _Assembly=Assembly.Load(Assembly.GetExecutingAssembly().FullName);
这条语句得到当前运行的Assembly
createObject=_Assembly.CreateInstance(typeName,
true,
System.Reflection.BindingFlags.CreateInstance,
null,
new object[]{context},//args
null,//CultureInfo
null);
这条语句则创建了指定的对象.
这个函数里的参数比较多.下面是引用msdn中:
public object CreateInstance(
string bool BindingFlags Binder object[] CultureInfo object[] );
ignoreCase
如果为 true,则忽略类型名的大小写;否则,为false。bindingAttr
影响执行搜索的方式的位屏蔽。此值是BindingFlags中的位标志的组合。
binder
一个对象,它启用绑定、参数类型的强制、成员的调用以及通过反射进行MemberInfo 对象的检索。如果 binder 为空引用(Visual Basic 中为 Nothing),则使用默认联编程序。 args
Object 类型的数组,包含要传递给构造函数的参数。此参数数组在数量、顺序和类型方面必须与要调用的构造函数的参数匹配。如果需要默认的构造函数,则 args 必须是空数组或空引用(Visual Basic 中为 Nothing)。
culture
用于控制类型强制的 CultureInfo 的实例。如果这是空引用(Visual Basic 中为 Nothing),则使用当前线程的 CultureInfo。(例如,这对于将表示 1000 的 String 转换为 Double 值是必需的,因为不同的区域性以不同的方式表示 1000。)
activationAttributes
Object 类型的数组,包含一个或多个可以参与激活的激活属性。激活属性的一个示例是:
URLAttribute(http://hostname/appname/objectURI)
返回值
表示此类型且匹配指定条件的 Object 的实例;如果没有找到typeName,则为空引用(Visual Basic 中为 Nothing)。
我的本意是想通过一个工厂方法来实现接口的动态实现.但是利用了.net框架中的反射机制,发现要达到我原来的目的这么容易就实现了.所以就没有使用原来的工厂方法来实现,通过下面简单的函数调用即可:
1 public IBuilder CreateBuilder()
2 {
3 if (null==section)
4 readConfigurationFile();
5 return (IBuilder)ConfigurationFactory.CreateObject(this,section.Builder.ToString());
6 }读取配置文件是通过函数readConfigurationFile()来实现的
1 /// <summary>
2 /// 取得配置文件
3 /// </summary>
4 private void readConfigurationFile()
5 {
6 try
7 {
8 System.Reflection.Assembly Asm = System.Reflection.Assembly.GetExecutingAssembly();
9 string SourcePath=Path.GetDirectoryName(Asm.Location);
10 SourcePath+=System.Configuration.ConfigurationSettings.AppSettings["MaunExcelConfig"];
11 section=XmlHelper.Read (setting.Key,SourcePath) as ManuSetting;
12 }
13 catch(System.IO.IOException ex)
14 {
15 throw new System.Configuration.ConfigurationException(SR.MessageConfigFileNotFound,ex);
16 }
17 catch(Exception ex)
18 {
19 throw new System.Configuration.ConfigurationException(SR.MessageConfigFileNotValidOrSectionNotFound,ex);
20 }
21 }
其中最主要的是section=XmlHelper.Read (setting.Key,SourcePath) as ManuSetting;这句
XmlHelper是我仿造微软的Configuration Application Block做的一个配置类.功能是可以把一个类序列化和反序列化.这里就不多说了,不熟悉的朋友可以到http://www.cnblogs.com/Terrylee/archive/2006/08/01/Enterprise_Library.html 这里去查看,有很详细的说明.
完整源代码:
1 public class TranContext:IDisposable
2 {
3 private readonly TranSetting setting=null;
4 private IBuilder builder=null;
5 private ILog log=null;
6 private ManuSetting section=null;
7 public event EndReportEventHandler EndReport;
8 public TranContext()
9 {
10 //
11 // TODO: 在此处添加构造函数逻辑
12 //
13 }
14 public TranContext(TranSetting setting)
15 {
16 ArgumentValidation.CheckForNullReference (setting,"TranSetting");
17 this.setting =setting;
18 }
19 public TranContext(string key,string askFileName,string operation)
20 {
21 ArgumentValidation.CheckForEmptyString (key,"key");
22 ArgumentValidation.CheckForEmptyString (askFileName,"askFileName");
23 ArgumentValidation.CheckForEmptyString (operation,"operation");
24 setting=new TranSetting (this,key,askFileName,operation);
25 }
26 public TranSetting Setting
27 {
28 get{return this.setting;}
29 }
30 public IBuilder Builder
31 {
32 get
33 {
34 if (null==builder)
35 builder=CreateBuilder();
36 return builder ;
37 }
38 }
39 public ILog Log
40 {
41 get
42 {
43 if (null==log)
44 log=CreateLog();
45 return log;
46 }
47 set{log=value;}
48 }
49 public IEntity Entity
50 {
51 get{return (IEntity)section.Entity;}
52 }
53 public ManuSetting Section
54 {
55 get
56 {
57 if (null==section)
58 {
59 readConfigurationFile();
60 }
61 return section;
62 }
63 set{section=value;}
64 }
65 public string ReturnFileName
66 {
67 get{return setting.ReturnFileName;}
68 }
69 /// <summary>
70 /// 取得配置文件
71 /// </summary>
72 private void readConfigurationFile()
73 {
74 try
75 {
76 System.Reflection.Assembly Asm = System.Reflection.Assembly.GetExecutingAssembly();
77 string SourcePath=Path.GetDirectoryName(Asm.Location);
78 SourcePath+=System.Configuration.ConfigurationSettings.AppSettings["MaunExcelConfig"];
79 section=XmlHelper.Read (setting.Key,SourcePath) as ManuSetting;
80 }
81 catch(System.IO.IOException ex)
82 {
83 throw new System.Configuration.ConfigurationException(SR.MessageConfigFileNotFound,ex);
84 }
85 catch(Exception ex)
86 {
87 throw new System.Configuration.ConfigurationException(SR.MessageConfigFileNotValidOrSectionNotFound,ex);
88 }
89 }
90 public void Execute()
91 {
92 using(ContextWatch watch=new ContextWatch (this))
93 {
94 watch.EndReport +=new EndReportEventHandler(OnEndReport);
95 watch.ExecuteContext();
96 }
97 }
98 public void Dispose()
99 {
100 // Dispose(true);
101 GC.SuppressFinalize(this);
102 }
103 // private void Dispose(bool disposing)
104 // {
105 // if (disposing)
106 // {
107 // if (this.watch != null)
108 // {
109 // this.watch.EndReport -= new EndReportEventHandler (OnEndReport);
110 // watch.Dispose();
111 // }
112 // }
113 // }
114 public IBuilder CreateBuilder()
115 {
116 if (null==section)
117 readConfigurationFile();
118 return (IBuilder)ConfigurationFactory.CreateObject(this,section.Builder.ToString());
119 }
120 public ILog CreateLog()
121 {
122 if (null==section)
123 readConfigurationFile();
124 return (ILog)ConfigurationFactory.CreateObject(this,section.Log.ToString());
125 }
126 public ITran CreateTran(object detail)
127 {
128 if (null==section)
129 readConfigurationFile();
130 return (ITran)ConfigurationFactory.CreateObject(detail,section.Tran.ToString());
131 }
132 private void OnEndReport(object sender,EndReportEventArgs e )
133 {
134 if (EndReport != null)
135 {
136 EndReport(this, e);
137 }
138 }
139
140 }