.NET人字拖
万丈高楼平地起,我正在努力筑地基...
随笔- 133  文章- 0  评论- 606 
博客园  社区  首页  新随笔  联系  管理  订阅 订阅

运用反射实现多层和多数据库开发

  现在很多项目都须要为将来的扩展考虑,当然数据库也是一个很重我要的方面,扩展自己的Provider,这就需要反射技术,虽然会对性能有所影响,但是性价比还是很高的哦,从PetShop和CommunityServer都可以看到反射技术啦,也可以说反射是最基本的啦,呵呵!他的老家是在System.Reflection,当我们要开工时首先就是要把他抓出来.

  要实现这一功能我们当然要知道Provider的程序集,和工作的类名了,在多层架够中才能让逻辑和数据进行沟通,这样也方便团队开发的协条款发展,我们通过PetShop和CommunityServer两个例子来说明一下.

  我们先看看PetShop的反射技术,在配制文件中发现如下配制:

        <!-- Pet Shop DAL configuration settings -->
        
<add key="WebDAL" value="PetShop.SQLServerDAL"/>
        
<add key="OrdersDAL" value="PetShop.SQLServerDAL"/>
        
<add key="ProfileDAL" value="PetShop.SQLProfileDAL"/>
  其实只从配制文件中得到程序集名称,一般程序集就是类所在命名空间,也就是编译后显示的DLL名称,那PetShop是怎样工作的,下面我们来看一下DataAccess类,这也可说成一个工厂,呵呵,我们来看一下代码:
 1using System.Reflection;
 2using System.Configuration;
 3
 4namespace PetShop.DALFactory {
 5
 6    /**//// <summary>
 7    /// This class is implemented following the Abstract Factory pattern to create the DAL implementation
 8    /// specified from the configuration file
 9    /// </summary>

10    public sealed class DataAccess {
11
12        // Look up the DAL implementation we should be using
13        private static readonly string path = ConfigurationManager.AppSettings["WebDAL"];
14        private static readonly string orderPath = ConfigurationManager.AppSettings["OrdersDAL"];
15        
16        private DataAccess() { }
17
18        public static PetShop.IDAL.ICategory CreateCategory() {
19            string className = path + ".Category";
20            return (PetShop.IDAL.ICategory)Assembly.Load(path).CreateInstance(className);
21        }

22
23        public static PetShop.IDAL.IInventory CreateInventory() {
24            string className = path + ".Inventory";
25            return (PetShop.IDAL.IInventory)Assembly.Load(path).CreateInstance(className);
26        }

27
28        public static PetShop.IDAL.IItem CreateItem() {
29            string className = path + ".Item";
30            return (PetShop.IDAL.IItem)Assembly.Load(path).CreateInstance(className);
31        }

32
33        public static PetShop.IDAL.IOrder CreateOrder() {
34            string className = orderPath + ".Order";
35            return (PetShop.IDAL.IOrder)Assembly.Load(orderPath).CreateInstance(className);
36        }

37
38        public static PetShop.IDAL.IProduct CreateProduct() {
39            string className = path + ".Product";
40            return (PetShop.IDAL.IProduct)Assembly.Load(path).CreateInstance(className);
41        }

42
43    }

44}
   其中(PetShop.IDAL.IProduct)Assembly.Load(path).CreateInstance(className);就是将类进行反射,首先要载入程序集,然后再创进类实例,通过静态方法就可以直接调用接口的方法等,从而实现了继承接口的类的反射,同时也方便表现层的数据传输.

   下面我们来看一下CommunityServer是怎么实现的,CS是一个大象极别的项目,所以他有很自己扩展Provider,那怎么样才能让他们工作呢?其实原理和上述的反射方法差不多,只不过CS用的是Object.GetTyp()而达到这项功能.当我第一次看到时,还一直为怎样传输ConnectionString&DataOwner而不解,后来打开源数据看了一下各个方法的注解后才理解.
 
  CS从自定的配制文件中读取Provider节点并缓存,这在CSConfiguration类中可以发现,在DataProviders类中就实现反射,通过能构造函数的反射查找最匹配的构造函数对类进行实例化,当然当他们遇到有ConnectionString&DataOwner两参数的构造函数时,就对其进行实例化,从而达到对他们值的传输.

 
DataProviders
  1//------------------------------------------------------------------------------
  2// <copyright company="Telligent Systems">
  3//     Copyright (c) Telligent Systems Corporation.  All rights reserved.
  4// </copyright> 
  5//------------------------------------------------------------------------------
  6
  7using System;
  8using System.Configuration;
  9using System.IO;
 10using System.Reflection;
 11using System.Web;
 12using CommunityServer.Configuration;
 13
 14namespace CommunityServer.Components
 15{
 16    /**//// <summary>
 17    /// DataProviders is responible for loading and managing the various CS DataProviders
 18    /// </summary>

 19    public sealed class DataProviders
 20    {
 21        /**//// <summary>
 22        /// This class can not be instantiated
 23        /// </summary>

 24        private DataProviders()
 25        {
 26        }

 27
 28        private static void GetDataStoreParameters(Provider dataProvider, out string connectionString, out string databaseOwner)
 29        {
 30            databaseOwner = dataProvider.Attributes["databaseOwner"];
 31            if(databaseOwner == null || databaseOwner.Trim().Length == 0)
 32                databaseOwner = ConfigurationSettings.AppSettings[dataProvider.Attributes["databaseOwnerStringName"]];
 33
 34            connectionString = dataProvider.Attributes["connectionString"];
 35            if(connectionString == null || connectionString.Trim().Length == 0)
 36                connectionString = ConfigurationSettings.AppSettings[dataProvider.Attributes["connectionStringName"]];
 37        }

 38
 39        /**//// <summary>
 40        /// Creates an instance of the provider using Activator. This instance should be
 41        /// cached since it is an expesivie operation
 42        /// </summary>

 43        public static object CreateInstance(Provider dataProvider)
 44        {
 45            //Find the current attributes
 46            string connectionString = null; //dataProvider.Attributes["connectionString"];
 47            string databaseOwner = null;// dataProvider.Attributes["databaseOwner"];
 48
 49            GetDataStoreParameters(dataProvider, out connectionString, out databaseOwner);
 50
 51            //Get the type
 52            Type type  = Type.GetType(dataProvider.Type);
 53
 54            object newObject = null;
 55            if(type != null)
 56            {
 57                newObject =  Activator.CreateInstance(type,new object[]{databaseOwner,connectionString});  
 58            }

 59            
 60            if(newObject == null) //If we can not create an instance, throw an exception
 61                ProviderException(dataProvider.Name);
 62
 63            return newObject;
 64        }

 65
 66        /**//// <summary>
 67        /// Creates and Caches the ConstructorInfo for the specified provider. 
 68        /// </summary>

 69        public static ConstructorInfo CreateConstructorInfo (Provider dataProvider) 
 70        {
 71
 72            // The assembly should be in \bin or GAC, so we simply need
 73            // to get an instance of the type
 74            //
 75            CSConfiguration config = CSConfiguration.GetConfig();
 76            ConstructorInfo providerCnstr = null;
 77            try 
 78            {
 79                //string providerTypeName = ((Provider) config.Providers[providerName]).Type;
 80                Type type  = Type.GetType( dataProvider.Type );
 81
 82                // Insert the type into the cache
 83                //
 84                Type[] paramTypes = new Type[2];
 85                paramTypes[0] = typeof(string);
 86                paramTypes[1] = typeof(string);
 87
 88                providerCnstr = type.GetConstructor(paramTypes);
 89
 90            }
 
 91            catch 
 92            {
 93                ProviderException(dataProvider.Name);
 94            }

 95
 96           if(providerCnstr == null)
 97               ProviderException(dataProvider.Name);
 98
 99            return providerCnstr;
100        }

101
102        /**//// <summary>
103        /// Creates an instance of the specified provider using the Cached
104        /// ConstructorInfo from CreateConstructorInfo
105        /// </summary>

106        public static object Invoke(Provider dataProvider)
107        {
108            object[] paramArray = new object[2];
109
110            
111            string dbOwner = null; 
112            string connstring = null;
113
114            GetDataStoreParameters(dataProvider, out connstring, out dbOwner);
115
116            paramArray[0] = dbOwner;
117            paramArray[1] = connstring;
118
119            return CreateConstructorInfo(dataProvider).Invoke(paramArray);
120        }

121
122        Exception#region Exception
123        private static void ProviderException(string providerName)
124        {
125            CSConfiguration config = CSConfiguration.GetConfig();
126            HttpContext context = HttpContext.Current;
127            if (context != null) 
128            {
129                    
130                // We can't load the dataprovider
131                //
132                StreamReader reader = new StreamReader( context.Server.MapPath("~/Languages/" + config.DefaultLanguage + "/errors/DataProvider.htm") );
133                string html = reader.ReadToEnd();
134                reader.Close();
135
136                html = html.Replace("[DATAPROVIDERCLASS]", providerName);
137                html = html.Replace("[DATAPROVIDERASSEMBLY]", providerName);
138                context.Response.Write(html);
139                context.Response.End();
140            }
 
141            else 
142            {
143                throw new CSException(CSExceptionType.DataProvider, "Unable to load " + providerName);
144            }

145        }

146        #endregion

147    }

148}


  文章是越写越不知道写些什么?CS有很多人研究他,应该会有关于这样的文章,不多说了,呵呵.

关于作者:网魂小兵

文章出处:http://xdotnet.cnblogs.com

本文可以随意转载,摘抄等非商业用途。

为了尊重作者成果,在转载和摘抄的时候请留下作者名称和出处。

绿色通道:好文要顶关注我收藏该文与我联系
posted @ 2006-10-11 19:12 网魂小兵 阅读(1053) 评论(0) 编辑 收藏
注册用户登录后才能发表评论,请 登录 或 注册,返回博客园首页。
首页博问闪存新闻园子招聘知识库
最新IT新闻:
· 最想要的Entity Framework功能
· 专访Jeffrey Richter:Windows 8是微软的重中之重
· 《福布斯》:谷歌进军硬件产品 难撼动苹果地位
· 美国空军拟最多购买1.8万台iPad 2
· 分析称专利之争让谷歌苹果两败俱伤
» 更多新闻...
最新知识库文章:
· 高级编程语言的发展历程
· 如何学习一门新的编程语言?
· 学习不同编程语言的重要性
· 为什么我喜欢富于表达性的编程语言
· 计算机专业的女生为什么要学编程
» 更多知识库文章...

China-pub 2011秋季教材巡展
China-Pub 计算机绝版图书按需印刷服务
Copyright ©2012 网魂小兵
Name:
网魂小兵
Addr:
福建厦门
MSN:
myxbing#hotmail.com
昵称:网魂小兵
园龄:5年11个月
粉丝:23
关注:0

搜索

 
 

常用链接

  • 我的随笔
  • 我的评论
  • 我的参与
  • 最新评论
  • 我的标签
  • 更多链接

我的标签

  • directx11(6)
  • direct3d 11(6)
  • 游戏编程(6)
  • c/c++(6)
  • vs2010(5)
  • wpf(4)
  • openssl(2)
  • direct3d坐标系(2)
  • vs2008(2)
  • xaml(2)
  • 更多

随笔分类(170)

  • AJAX(doc)(8)
  • ASP.NET(46)
  • C#3.0+(13)
  • C/C++(27)
  • CommunityServer(7)
  • Database(11)
  • Enterprise Library (7)
  • JavaScript(10)
  • ServerContols(7)
  • UML(1)
  • VC++/MFC(8)
  • WPF/SilverLight(6)
  • XNA Game(2)
  • 翻译(4)
  • 今天我当家(11)
  • 设计模式(2)

随笔档案(133)

  • 2012年2月 (3)
  • 2011年8月 (3)
  • 2011年7月 (7)
  • 2011年5月 (1)
  • 2011年4月 (2)
  • 2011年2月 (1)
  • 2010年1月 (1)
  • 2009年3月 (3)
  • 2009年1月 (8)
  • 2008年3月 (1)
  • 2008年2月 (3)
  • 2008年1月 (1)
  • 2007年11月 (4)
  • 2007年10月 (3)
  • 2007年9月 (9)
  • 2007年8月 (3)
  • 2007年7月 (2)
  • 2007年6月 (9)
  • 2007年5月 (9)
  • 2007年4月 (14)
  • 2007年3月 (6)
  • 2007年2月 (3)
  • 2007年1月 (15)
  • 2006年12月 (9)
  • 2006年11月 (2)
  • 2006年10月 (4)
  • 2006年9月 (7)

文章分类

  • Asp.Net(.NET)

I Like Links

  • ASP.NET
  • Codeplex
  • XNADevelopment

My Friend's Blog

  • 陆巍杰
  • 孙小雨
  • 探丫头
  • 网络安全&Linux

积分与排名

  • 积分 - 283912
  • 排名 - 248

最新评论

阅读排行榜

评论排行榜