首先从最常用的数据获取块开始下手。
我们每次使用数据获取块首先做的就是得到一个Database
Database db = DatabaseFactory.CreateDatabase()
我们首先从DatabaseFactory着手
从名字上即可以猜测,DatabaseFactory是工厂模式的应用,用来创建一个恰当的Database。我们知道DAAB是兼容多种数据库的(MSSQL,Oracle等),因此所创建的Database应该是特异化的Database,比如SqlDatabase,从源代码的结构上看也是这样的。
再来看DatabaseFactory的代码
public static class DatabaseFactory
DatabaseFactory是一个静态类,其中只含有静态方法
public static Database CreateDatabase();
public static Database CreateDatabase(string name);
private static void TryLogConfigurationError(ConfigurationErrorsException configurationException, string instanceName)
我们关注的是CreateDatabase方法,这两个方法差不多,不过一个是得到默认Database一个是得到指定的Database
1: public static Database CreateDatabase()
2: {
3: try
4: {
5: DatabaseProviderFactory factory = new DatabaseProviderFactory(ConfigurationSourceFactory.Create());
6: return factory.CreateDefault();
7: }
8: catch (ConfigurationErrorsException configurationException)
9: {
10: TryLogConfigurationError(configurationException, "default");
11:
12: throw;
13: }
14: }
从上面的代码我们可以发现DatabaseFactory是从DatabaseProviderFactory获得了Database并返回的,同时尝试把发生的错误记录下来,然后异常又被再次抛出了。
对于异常的处理并不是我们关心的,我们继续去看DatabaseProviderFactory。
1: public class DatabaseProviderFactory : NameTypeFactoryBase<Database>2: {
3: /// <summary>4: /// <para>Initializes a new instance of the <see cref="DatabaseProviderFactory"/> class5: /// with the default configuration source.</para>6: /// </summary>7: protected DatabaseProviderFactory()8: : base()9: {
10: }
11:
12: /// <summary>
13: /// <para>Initializes a new instance of the <see cref="DatabaseProviderFactory"/> class14: /// with the given configuration source.</para>15: /// </summary>16: /// <param name="configurationSource">The source for configuration information.</param>17: public DatabaseProviderFactory(IConfigurationSource configurationSource)18: : base(configurationSource)19: {}
20:
21: }
可以知道,DatabaseFactory用ConfigurationSourceFactory创建的一个配置源装配了DatabaseProviderFactory。看来重点在NameTypeFactoryBase上。
我们来看NameTypeFactoryBase。
1: /// <summary>2: /// Base class for instance factories.3: /// </summary>4: /// <remarks>5: /// This class is used to create instances of types compatible with <typeparamref name="T"/> described6: /// by a configuration source.7: /// </remarks>8: public class NameTypeFactoryBase<T>9: {
10: private IConfigurationSource configurationSource;11:
12: /// <summary>13: /// Initializes a new instance of the <see cref="NameTypeFactoryBase{T}"/> class with the default configuration source.14: /// </summary>15: protected NameTypeFactoryBase()16: : this(ConfigurationSourceFactory.Create())17: {
18: }
19:
20: /// <summary>21: /// Initializes a new instance of the <see cref="NameTypeFactoryBase{T}"/> class with a configuration source.22: /// </summary>23: /// <param name="configurationSource">The configuration source to use.</param>24: protected NameTypeFactoryBase(IConfigurationSource configurationSource)25: {
26: this.configurationSource = configurationSource;27: }
28:
29: /// <summary>30: /// Returns a new instance of <typeparamref name="T"/> based on the default instance configuration.31: /// </summary>32: /// <returns>33: /// A new instance of <typeparamref name="T"/>.34: /// </returns>35: public T CreateDefault()36: {
37: return EnterpriseLibraryFactory.BuildUp<T>(configurationSource);38: }
39:
40: /// <summary>41: /// Returns an new instance of <typeparamref name="T"/> based on the configuration for <paramref name="name"/>.42: /// </summary>43: /// <param name="name">The name of the required instance.</param>44: /// <returns>45: /// A new instance of <typeparamref name="T"/>.46: /// </returns>47: public T Create(string name)48: {
49: return EnterpriseLibraryFactory.BuildUp<T>(name, configurationSource);50: }
51: }
回忆DatabaseFactory类,在创建了一个DatabaseProviderFactory后即调用了其Create或CreateDefault方法,这两个方法都是由NameTypeFactoryBase<Database>继承的。从这里可以看出,NameTypeFactoryBase用EnterpriseLibraryFactory从配置源读取配置并装配了Database类。
我们继续挖掘到EnterpriseLibraryFactory类。
public static class EnterpriseLibraryFactory这也是一个静态类。这个类代码比较多,我就拣几段重要的贴上来。
1: static EnterpriseLibraryFactory()2: {
3: builder = new Builder();4: StagedStrategyChain<BuilderStage> stagedStrategyChain = new StagedStrategyChain<BuilderStage>();5: stagedStrategyChain.AddNew<ConfigurationNameMappingStrategy>(BuilderStage.PreCreation);
6: stagedStrategyChain.AddNew<LocatorLookupStrategy>(BuilderStage.PreCreation);
7: stagedStrategyChain.AddNew<ConfiguredObjectStrategy>(BuilderStage.PreCreation);
8: stagedStrategyChain.AddNew<InstrumentationStrategy>(BuilderStage.PostInitialization);
9: strategyChain = stagedStrategyChain.MakeStrategyChain();
10: }
1: public static T BuildUp<T>(IConfigurationSource configurationSource)2: {
3: return BuildUp<T>(null, null, configurationSource);4: }
5:
6: public static T BuildUp<T>(IReadWriteLocator locator,7: ILifetimeContainer lifetimeContainer,
8: IConfigurationSource configurationSource)
9: {
10: if (configurationSource == null)11: throw new ArgumentNullException("configurationSource");12:
13: try14: {
15: return GetObjectBuilder()16: .BuildUp<T>(locator,
17: lifetimeContainer,
18: GetPolicies(configurationSource),
19: strategyChain,
20: NamedTypeBuildKey.Make<T>(),
21: null);22:
23: }
24: catch (BuildFailedException e)25: {
26: // look for the wrapped ConfigurationErrorsException, if any, and throw it27: ConfigurationErrorsException cee = GetConfigurationErrorsException(e);
28: if (cee != null)29: {
30: throw cee;31: }
32:
33: // unknown exception, bubble it up34: throw;35: }
36: }
1: private static PolicyList GetPolicies(IConfigurationSource configurationSource)2: {
3: PolicyList policyList = new PolicyList();4: policyList.Set<IConfigurationObjectPolicy>(new ConfigurationObjectPolicy(configurationSource),5: typeof(IConfigurationSource));6: policyList.Set<IReflectionCachePolicy>(new ReflectionCachePolicy(reflectionCache),7: typeof(IReflectionCachePolicy));8:
9: return policyList;10: }
11:
12: private static IBuilder GetObjectBuilder()13: {
14: return builder;15: }
16:
17: private static IConfigurationSource ConfigurationSource18: {
19: get { return ConfigurationSourceFactory.Create(); }20: }
熟悉Unity的朋友应该能猜到,大概是按照StrategyChain对Database进行了装配。
现在关键就在builder上了,可是Builder是ObjectBuilder2中的类,没有源码。
今天的工作先到这里了。