在学习SQLCenter的时候,对老大说的Generators设计中用到了
默认代理模式和Ioc模式有点问题。刚才晚上又重新看了下,哈哈,有点醍醐灌顶的感觉。确实如此。下面写写自己的体会。
默认代理模式就不多说了。主要看Ioc的体现,因为最近我正在学习Spring.Net,所以对Ioc,AOP这样的字眼特别敏感。
关于Ioc,园子里面有太多的好文章。我简单描述我的感觉,同时联系下SQLCenter.
Ioc的出现,是为了解耦。使类或组件尽可能的“不和陌生人说话”。但是他们又必须有这样的联系,怎么办呢?这就出现了Ioc容器。通过这样的容器来管理这些组件之间的联系。这样的容器在.Net下有Spring.Net,Castle,java下还有PicoContainer,Hiemind,XWork等。在Ioc中这些framework成了主程序的角色,负责协调事件和应用的活动,还有生命周期等。
在SqlCenter中GeneratorService在一定程度上扮演了这样一个角色。它通过配置文件获得组件之间的关系,负责创建和调度。当然目前还没有全部完成这样一个容器的功能,但是思想上已经充分体现了Ioc模式。
看下部分配置:

配置信息
1
<generators>
2
<item target="SqlCenter.Entities.Field, SqlCenter.Entities" type="default" generator="SqlCenter.Generators.FieldGenerator, SqlCenter.Generators"/>
3
<item target="SqlCenter.Entities.Order, SqlCenter.Entities" type="default" generator="SqlCenter.Generators.OrderGenerator, SqlCenter.Generators"/>
4
<item target="SqlCenter.Entities.Join, SqlCenter.Entities" type="default" generator="SqlCenter.Generators.JoinGenerator, SqlCenter.Generators"/>
5
<item target="SqlCenter.Entities.FromTable, SqlCenter.Entities" type="default" generator="SqlCenter.Generators.FromTableGenerator, SqlCenter.Generators"/>
6


7
</generators>然后主要通过这个NativeGetCalculator方法实现了容器的基本功能:

简单容器
1
private static object NativeGetCalculator(NameObjectCollection cache,CalculatorConfigurationCollection configurations,Type expressionType, string dbType)
2
{
3
dbType=dbType.ToLower().Trim();
4
Hashtable item=cache[dbType] as Hashtable;
5
if (item==null)
6
{
7
lock(cache)
8
{
9
item=new Hashtable();
10
cache.Add(dbType,item);
11
}
12
}
13
object calculator=item[expressionType];
14
if(calculator==null)
15
{
16
CalculatorConfiguration config=configurations.FromTarget(expressionType,dbType);
17
if(config!=null)
18
{
19
lock(item)
20
{
21
if(calculator!=null)
22
{
23
calculator=Activator.CreateInstance(config.Calculator, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, null, new object[] {}, null);
24
item.Add(expressionType,calculator);
25
}
26
}
27
}
28
else if(string.Compare(dbType,"default",true)!=0)
29
{
30
config=configurations.FromTarget(expressionType,"default");
31
if(config!=null)
32
{
33
lock(item)
34
{
35
if(calculator==null)
36
{
37
calculator=Activator.CreateInstance(config.Calculator, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, null, new object[] {}, null);
38
if(calculator is IGenerator)
39
{
40
((IGenerator)calculator).Type=dbType;
41
}
42
item.Add(expressionType,calculator);
43
}
44
}
45
}
46
}
47
}
48
return calculator;
49
}
50
通过这样的实现,就能够实现组件的“热插拔”和组件关系的容器管理。
今天终于调试通过了自己的基于Spring.Net的一个简单demo.再回头看看SQLCenter,我对自己说:这就是Ioc精神!
对了,还有一个需要注意的。当然这个注意点很小,也许是因为我对配置写程序的不熟悉。调试自己demo的时候,总是有问题。最后在老大的指导下,才发现原来是对这个配置的错误理解:
<item target="SqlCenter.Entities.FromTable, SqlCenter.Entities" type="default" generator="SqlCenter.Generators.FromTableGenerator, SqlCenter.Generators"/>
这里面的generator怎么写? ====>
NameSpace.ClassName, Assembly