当前位置: 首页 >> 程序设计 >> Websharp:开源.Net应用系统框架
 

Websharp:开源.Net应用系统框架

作者:      来源:http://blog.csdn.net/sunny_y_m     发表时间:2006-12-26     浏览次数:      字号:    

一.     前言

Websharp的目标,是开发一个开源的基于Microsoft.Net的轻量级的应用软件系统开发框架,包含以下内容:

Ø         一个轻量级的O/R Mapping框架

Ø         一个轻量级的AOP框架

Ø         一个轻量级的ServiceLocator,主要目的是为整合不同服务端技术的客户端编程。

说来惭愧的是,这个框架从三年前就开始做了,但是因为工作的原因,具体的开发过程一直是断断续续,中间因个人对编程思想认识的变化,在结构方面也一直有点变化。在这个过程中,一直有人来Mail询问相关的情况,也有很多朋友发信来鼓励我,使我感到愧疚的是,我一直都没有很好的回复这些邮件。在国内,做开源项目真的是很难,首先要养活自己和老婆孩子,才能够挤出一点点时间来做自己的事情。

最近,因为工作的变化,使我从繁复的开发工作中脱离出来,使我有更多的时间来支配我自己,因此,又把这个工作继续了下去,经过一段时间的“虾米”生活,终于把O/R Mapping做的比较像样了。AOPServiceLocator部分,是以前做好的,一直都没有动过。现在我把所有的代码都公开出来,并写了一个简单的使用说明,希望能够对大家有所帮助。在这里,需要感谢的是徐芳波,在Websharp的开发过程中,也做了很多的工作,付出了很多。

本文主要说明Websharp O/R Mapping部分使用的内容。关于Websharp的设计理念,以及其他方面的内容,可以访问我的Bloghttp://sunnyym.cnblogs.com/  

从此处下载全部源代码

 

二.     Websharp O/R Mapping起步

Websharp ORM是一个轻量级的O/R Mapping框架,主要特点是抛弃了Java中常见的,也是其他一些O/R Mapping产品中使用XML文件来做映射描述的方法,而使用Attribute作为描述映射的方法,简单明了,并且,对开发人员来说,只有PersistenceManagerQueryTransaction等极少数接口需要掌握,上手快,使用非常方便。

因为在某些地方使用了范型,所以目前版本的Websharp需要.Net Framework2.0

下面的例子给出了使用Websharp进行ORM操作的基本过程。

       使用Visual Studio.Net2005建立一个Windows Console项目,然后,定义如下一个类:

    [TableMap("Product", "ID")]

    public class Product

    {

        private int m_ID;

        private string m_Name;

        private decimal m_Price;

 

        public Product() { }

        public Product(string name,decimal price)

        {

            //m_ID = id;

            m_Name = name;

            m_Price = price;

        }

 

        [ColumnMap("ID", DbType.Int32)]  

        [AutoIncrease(1)]

        public int ID

        {

            get { return m_ID; }

            set { m_ID = value; }

        }

 

        [ColumnMap("Name", DbType.String)]  

        public string Name

        {

            get { return m_Name; }

            set { m_Name = value; }

        }

 

        [ColumnMap("Price", DbType.Decimal)]  

        public decimal Price

        {

            get { return m_Price; }

            set { m_Price = value; }

        }

    }

类中第一行[TableMap("Product", "ID")]的意思是说,这个Product类映射到数据库中的Product表,主键为属性ID。在属性ID上,[ColumnMap("ID", DbType.Int32)]的意思是说,这个属性映射到数据库中的ID字段,数据类型是Int32[AutoIncrease(1)]表明这是一个自动增长列,增长的幅度为1。其他属性的可以据此类推。

因此,上面这个Produc类对应的数据库表的结构应该是:

字段名

数据类型

ID

int(自动增长)

Name

Nvarchar(50)

Price

Decimal

下面的代码演示了Websharp是如何把Product对象新增到数据库中的。

public static void Main(string[] args)

{

         //设定环境

    DatabaseProperty dbp = new DatabaseProperty();

    dbp.DatabaseType = DatabaseType.MSSQLServer;

    dbp.ConnectionString = "Data Source=(local);Initial Catalog=WebsharpTest;Integrated Security=True";

 

         //操作数据

    PersistenceManager pm = PersistenceManagerFactory.Instance().Create(dbp);

    Product p0 = new Product("Name0", 100);

    pm.PersistNew(p0);

    Product p1 = new Product("Name1", 101);

    pm.PersistNew(p1);

    pm.Flush();

    pm.Close();

}

在代码的开始部分,先设定了数据库的一些参数,然后,通过PersistenceManagerFactory创建了一个PersistenceManager,用这个PersistenceManager就可以对对象进行操作了。在上面的代码里面,我们把两个Product对象保存到了数据库中。注意,因为Product类的ID属性是自动增长的,因此,在保存这两个对象之前,是不必对ID属性赋值的,在这两个对象被保存到数据库中后,PersistenceManager会根据数据库中的自动增长的值自动给ID赋值。

当然,为了使上面的代码能够顺利运行,我们还需要做一些配置。新建一个App.config文件,把下面的配置代码Copy进去就可以了:

<?xml version="1.0" encoding="utf-8" ?>

<configuration>

  <configSections>

    <section name="cachingConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Caching.Configuration.CacheManagerSettings, Microsoft.Practices.EnterpriseLibrary.Caching, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null" />

    <section name="WebsharpExpirationPolicy" type="Websharp.ORM.Service.WebsharpCofigurationHandler,Websharp.ORM.Service" />

  </configSections>

  <cachingConfiguration defaultCacheManager="Cache Manager">

    <cacheManagers>

      <add expirationPollFrequencyInSeconds="60" maximumElementsInCacheBeforeScavenging="1000"

        numberToRemoveWhenScavenging="10" backingStoreName="Null Storage"

        name="Cache Manager" />

      <add expirationPollFrequencyInSeconds="60" maximumElementsInCacheBeforeScavenging="1000"

        numberToRemoveWhenScavenging="10" backingStoreName="Null Storage"

        name="EntityCache" />

      <add expirationPollFrequencyInSeconds="60" maximumElementsInCacheBeforeScavenging="1000"

        numberToRemoveWhenScavenging="10" backingStoreName="Null Storage"

        name="SqlCache" />

    </cacheManagers>

    <backingStores>

      <add encryptionProviderName="" type="Microsoft.Practices.EnterpriseLibrary.Caching.BackingStoreImplementations.NullBackingStore, Microsoft.Practices.EnterpriseLibrary.Caching, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null"

        name="Null Storage" />

    </backingStores>

  </cachingConfiguration>

 

  <WebsharpExpirationPolicy>

    <ExpirationPolicy ExpirationCheckInterval="60" AssemblyName="Microsoft.ApplicationBlocks.Cache" ClassName="Microsoft.ApplicationBlocks.Cache.ExpirationsImplementations.SlidingTime" />

  </WebsharpExpirationPolicy>

</configuration>

配置文件只是用来说明缓存的使用的,基本上所有的项目需要的配置文件对于Websharp来说都不需要改变。当然,有一些细微的参数还是可以调整的,这个在后面描述。

可以看出,相对于其他一些O/R Mapping框架来说,Websharp不需要写一大堆的XML映射文件,代码简洁明了。

三.     映射方法说明

映射部分,完成对象和关系型数据库之间映射关系的表达。Websharp使用Attribute来描述映射关系,设计了以下Attribute来描述对象和关系型数据库之间的映射。

Ø        TableMapAttribute

这个Attribute描述对象和数据库表的映射关系,这个类有两个属性,TableName属性指明和某个类所对应的数据库表,PrimaryKeys用来描述表的主关键字。这个类的定义如下:

         [AttributeUsage(AttributeTargets.Class)]

         public class TableMapAttribute : Attribute

         {

                   private string tableName;

                   private string[] primaryKeys;

                   public TableMapAttribute(string tableName,params string[] primaryKeys)

                   {

                            this.tableName = tableName;

                            this.primaryKeys = primaryKeys;

                   }

                   public string TableName

                   {

                            get{return tableName;}

                            set{tableName = value;}

                   }

                  

                   public string[] PrimaryKeys

                   {

                            get{return primaryKeys;}

                            set{primaryKeys = value;}

                   }

         }

 

Ø               ColumnMapAttribute

这个Attribute描述对象属性和数据库中表的字段之间的映射关系,这个类有三个属性,ColumnName属性指明和某个属性所对应的字段,DbType属性指明数据库字段的数据类型,DefaultValue指明字段的默认值。这个类的定义如下:

         [AttributeUsage(AttributeTargets.Property)]

         public class ColumnMapAttribute : Attribute

         {

                   private string columnName;

                   private DbType dbtype;

                   private object defaultValue;

                   public ColumnMapAttribute(string columnName,DbType dbtype)

                   {

                            this.columnName = columnName;

                            this.dbtype = dbtype;

                   }

 

                   public ColumnMapAttribute(string columnName,DbType dbtype,object defaultValue)

                   {

                            this.columnName = columnName;

                            this.dbtype = dbtype;

                            this.defaultValue = defaultValue;

                   }

 

                   public string ColumnName

                   {

                            get{return columnName;}

                            set{columnName = value;}

                   }

 

                   public DbType DbType

                   {

                            get{return dbtype;}

                            set{dbtype = value;}

                   }

                  

                   public object DefaultValue

                   {

                            get{return defaultValue;}

                            set{defaultValue = value;}

                   }

         }

 

Ø        ReferenceObjectAttribute

ReferenceObjectAttribute指示该属性是引用的另外一个对象,因此,在执行持久化操作的时候,需要根据参数进行额外的处理。默认情况下,当持久化实体对象的时候,ReferenceObjectAttribute指示的属性,不进行操作。这个类有三个属性,ReferenceType指明所引用的对象的类型,PrimaryKeyForeignKey用来指明两个类之间进行关联的主键和外键。这个类的定义如下:

         [AttributeUsage(AttributeTargets.Property)]

         public class ReferenceObjectAttribute : Attribute

         {

                   private Type referenceType;

                   private string primaryKey;

                   private string foreignKey;

                   public ReferenceObjectAttribute(Type referenceType,string primaryKey,string foreignKey)

                   {

                            this.referenceType = referenceType;

                            this.primaryKey = primaryKey;

                            this.foreignKey = foreignKey;

                   }

 

                   public ReferenceObjectAttribute(){}

 

                   public Type ReferenceType

                   {

                            get{return referenceType;}

                            set{referenceType = value;}

                   }

 

                   public string PrimaryKey

                   {

                            get{return primaryKey;}

                            set{primaryKey = value;}

                   }

 

                   public string ForeignKey

                   {

                            get{return foreignKey;}