首先从最常用的数据获取块开始下手。
我们每次使用数据获取块首先做的就是得到一个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"/> class
5: /// 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"/> class
14: /// 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"/> described
6: /// 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: try
14: {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 it
27: ConfigurationErrorsException cee = GetConfigurationErrorsException(e);28: if (cee != null)
29: {30: throw cee;
31: } 32: 33: // unknown exception, bubble it up
34: 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 ConfigurationSource
18: {19: get { return ConfigurationSourceFactory.Create(); }
20: }熟悉Unity的朋友应该能猜到,大概是按照StrategyChain对Database进行了装配。
现在关键就在builder上了,可是Builder是ObjectBuilder2中的类,没有源码。
今天的工作先到这里了。
