微软企业库源码解析——DAAB(一)DatabaseFactory
首先从最常用的数据获取块开始下手。
我们每次使用数据获取块首先做的就是得到一个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中的类,没有源码。
今天的工作先到这里了。