人生是一场不能存盘的RPG,我只能尽量多搞几个Screenshot

November 10, 2006

Cool Javescript

Filed under: 代码学习

javascript:R=0; x1=.1; y1=.05; x2=.25; y2=.24; x3=1.6; y3=.24; x4=300; y4=200; x5=300; y5=200; DI=document.images; DIL=DI.length; function A(){for(i=0; i-DIL; i++){DIS=DI[ i ].style; DIS.position=’absolute’; DIS.left=Math.sin(R*x1+i*x2+x3)*x4+x5; DIS.top=Math.cos(R*y1+i*y2+y3)*y4+y5}R++}setInterval(’A()’,5); void(0);

Open a web page contains image, and copy the code snippet into IE’s address, GO!

August 19, 2006

PetShop的Order和Message Queuing

Filed under: 代码学习

MSMQ与XML Web Services和.Net Remoting一样,是一种分布式开发技术。但是在使用XML Web Services或
.Net Remoting组件时,Client端需要和Server端实时交换信息,Server需要保持联机。
MSMQ以异步的方式和Server端交互,不用担心等待Server端的长时间处理过程。
在Server离线的情况下工作,将Message临时保存在Client端的消息队列中,以后联机时再发送到Server端处理。

在.Net环境下编写简单的Message Queue程序

安装Message Queuing Services
Control Panel->Add/Remove Programs->Add/Remove Windows Components安装MSMQ。

PetShop中的MesageQueuing

1. Factory class, create order Messaging implementation specified from the configuration file.

PetShop.MessagingFactory.QueueAccess
{
private static readonly string path = ConfigurationManager.AppSettings[”OrderMessaging”];

private QueueAccess() { }

public static PetShop.IMessaging.IOrder CreateOrder()
{
string className = path + “.Order”;
return (PetShop.IMessaging.IOrder)Assembly.Load(path).CreateInstance(className);
}
}

2. PetShop.IMessaging.IOrder

public interface IOrder
{
OrderInfo Receive();

OrderInfo Receive(int timeout);

void Send(OrderInfo orderMessage);
}

3. 通过transactional queue收发message的类的base class.
public class PetShopQueue : IDisposable
{

}

4. 具体类,通过MSMQ收发订单
PetShop.MSMQMessaging.Order: PetShopQueue, PetShop.IMessaging.IOrder
{

}

参考:
监视消息队列
http://www.netscum.dk/technet/prodtechnol/windowsserver2003/zh-CHS/library/RMS/RMSoperationsTC/a7109399-3a84-4681-874b-f6ea1646b0a0.mspx?mfr=true
.Net快速入门
http://chs.gotdotnet.com/quickstart/howto/doc/sendobject.aspx

PetShop中的OracleMembershipProvide

Filed under: 代码学习

Asp.net的membership缺省是放在sql server或 sql server exp中的,
如果使用Oracle就需要实现自己的memebership Provider.

Provider模式乃Asp.net2.0架构中精华之一,同时memebership也是ASP.Net2.0的要点.

1.web.config中
<membership defaultProvider=”SQLMembershipProvider”>
<providers>
<add name=”SQLMembershipProvider”
type=”System.Web.Security.SqlMembershipProvider”
connectionStringName=”SQLMembershipConnString”
applicationName=”.NET Pet Shop 4.0″
enablePasswordRetrieval=”false”
enablePasswordReset=”true”
requiresQuestionAndAnswer=”false”
requiresUniqueEmail=”false”
passwordFormat=”Hashed”/>
</providers>
</membership>

<!– Membership Provider for Oracle –>
<!–
<membership defaultProvider=”OracleMembershipProvider”>
<providers>
<clear/>
<add name=”OracleMembershipProvider”
type=”PetShop.Membership.OracleMembershipProvider”
connectionStringName=”OraMembershipConnString”
enablePasswordRetrieval=”false”
enablePasswordReset=”false”
requiresUniqueEmail=”false”
requiresQuestionAndAnswer=”false”
minRequiredPasswordLength=”7″
minRequiredNonalphanumericCharacters=”1″
applicationName=”.NET Pet Shop 4.0″
hashAlgorithmType=”SHA1″
passwordFormat=”Hashed”/>
</providers>
</membership>
–>
这里有一些配置需要注意, passwordFormat为”Hashed”时无法取回password,只能reset,此时若
enablePasswordRetrieval设为true,会出错.

if(passwordFormat == MembershipPasswordFormat.Hashed && enablePasswordRetrieval)
throw new ProviderException(”Provider cannot retrieve hashed password”);

2. Oracle的Membership表
CREATE TABLE MSPETSHOP4SERVICES.MEMBERSHIP (
UserId number NOT NULL,
Password varchar2(128 byte) NOT NULL,
PasswordFormat number NOT NULL,
MobilePin varchar2(16 byte),
Email varchar2(128 byte),
PasswordQuestion varchar2(256 byte),
PasswordAnswer varchar2(128 byte),
IsApproved char(1 byte) NOT NULL,
CreatedDate date NOT NULL,
LastLoginDate date NOT NULL,
LastPasswordChangedDate date NOT NULL,
“Comment” varchar2(4000 byte),
PasswordSalt varchar2(128 byte),
CONSTRAINT PK_MEMBERSHIP PRIMARY KEY(UserId),
CONSTRAINT FK_MEMBERSHIP_USERS FOREIGN KEY(UserId)
REFERENCES MSPETSHOP4SERVICES.USERS(UserId)
ON DELETE CASCADE);

3.OracleMembershipProvider 代码实现:

很多都没有实现.

可参照
Writing A Custom Membership Provider for your ASP.NET 2.0 Web Site

Building Custom Providers for ASP.NET 2.0 Membership

PetShop的Data Cache

Filed under: 代码学习

1.Interface
为了工厂模式的需要,PetShopCacheDependency会返回一个包含多个CacheDependency object的AggregateCacheDependency
public interface IPetShopCacheDependency
{
AggregateCacheDependency GetDependency();
}

2.工厂
CacheDependencyFactory模块中的
DependencyAccess会根据web.config的设定生成具体的PetShopCacheDependency

public static class DependencyAccess
{
public static IPetShopCacheDependency CreateProductDependency()
{
return LoadInstance(”Product”);
}

private static IPetShopCacheDependency LoadInstance(string className)
{
string path = ConfigurationManager.AppSettings[”CacheDependencyAssembly”];
string fullyQualifiedClass = path + “.” + className;

//所有的PetShopCacheDependency存在于一个assembly中
return (IPetShopCacheDependency)Assembly.Load(path).CreateInstance(fullyQualifiedClass);
}
}

web.config
<add key=”CacheDependencyAssembly” value=”PetShop.TableCacheDependency”/>

3.具体实现
提供了SQLserver Cache Dependency的通用实现,从web.config中读取table name并生成相应的
AggregateCacheDependency对象.
public abstract class TableDependency : PetShop.ICacheDependency.IPetShopCacheDependency
{
protected char[] configurationSeparator = new char[] { ‘,’ };

protected AggregateCacheDependency dependency = new AggregateCacheDependency();

protected TableDependency(string configKey)
{
string dbName = ConfigurationManager.AppSettings[”CacheDatabaseName”];
string tableConfig = ConfigurationManager.AppSettings[configKey];
string[] tables = tableConfig.Split(configurationSeparator);

foreach (string tableName in tables)
{
//注意dbName要和<caching>一节定义的database对应
dependency.Add(new SqlCacheDependency(dbName, tableName));
}
}

public AggregateCacheDependency GetDependency()
{
return dependency;
}
}

public class Product : TableDependency
{
public Product() : base(”ProductTableDependency”)
{
}
}

web.config
<!– CacheDatabaseName should match the name under caching section, when using TableCacheDependency –>
<add key=”CacheDatabaseName” value=”MSPetShop4″/>
<!– *TableDependency lists table dependency for each instance separated by comma –>
<add key=”CategoryTableDependency” value=”Category”/>
<add key=”ProductTableDependency” value=”Product,Category”/>
<add key=”ItemTableDependency” value=”Product,Category,Item”/>

<caching>
<sqlCacheDependency enabled=”true” pollTime=”10000″>
<databases>
<add name=”MSPetShop4″ connectionStringName=”SQLConnString1″ pollTime=”10000″/>
</databases>
</sqlCacheDependency>
</caching>

4.应用:
App_Code中定义了DataProxy类来获取数据,数据可能来自databse,亦可来自cache.
以ProductDataProxy为例,该类封装了BLL层的Product对象,通过Product读取数据,并放入cache

public static class ProductDataProxy
{
}

5. 数据库中的AspNet_SqlCacheTablesForChangeNotification是如何生成的?
使用工具
aspnet_regsql -S <SqlServerName> -U sa -d <DatabaseName> -ed -et -t <TableName>

见<Pet Shop 4 Install Folder>\DatabaseScripts\InstallDatabases.cmd:
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_regsql -S localhost -E -d MSPetShop4 -ed
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_regsql -S localhost -E -d MSPetShop4 -t Item -et
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_regsql -S localhost -E -d MSPetShop4 -t Product -et
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_regsql -S localhost -E -d MSPetShop4 -t Category -et

PetShop动态加载Pattern

Filed under: 代码学习

加载Order strategy,见Order class
1. Interface
public interface IOrderStrategy
{
void Insert(PetShop.Model.OrderInfo order);
}

2. Concrete class
public class OrderAsynchronous : IOrderStrategy
{
private static readonly PetShop.IMessaging.IOrder asynchOrder = PetShop.MessagingFactory.QueueAccess.CreateOrder();

public void Insert(PetShop.Model.OrderInfo order) {

asynchOrder.Send(order);
}
}

3.Factory
private static PetShop.IBLLStrategy.IOrderStrategy LoadInsertStrategy()
{

// Look up which strategy to use from config file
string path = ConfigurationManager.AppSettings[”OrderStrategyAssembly”];
string className = ConfigurationManager.AppSettings[”OrderStrategyClass”];

// Using the evidence given in the config file load the appropriate assembly and class
return (PetShop.IBLLStrategy.IOrderStrategy)Assembly.Load(path).CreateInstance(className);
}

4.web.Config
<add key=”OrderStrategyClass” value=”PetShop.BLL.OrderSynchronous”/>

PetShop Connection string加解密

Filed under: 代码学习

EncryptWebConfig.bat
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_regiis.exe -pef “connectionStrings” “C:\Program Files\Microsoft\.NET Pet Shop 4.0\Web”

DecryptWebConfig.bat
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_regiis.exe -pdf “connectionStrings” “C:\Program Files\Microsoft\.NET Pet Shop 4.0\Web”

另:可通过代码加解密的connection string
public void EncryptConfig(bool bEncrypt)
{
string path = “/tricks”;

Configuration config = WebConfigurationManager.OpWebConfiguration(path);
ConfigurationSection appSettings = config.GetSection(”connectionString”);

if(bEncrypt)
{
appSettings.SetionInformation.ProtectSection(”DataProtectionConfigurationProvider”);
}
else
{
appSettings.SetionInformation.UnprotectSection();
}
config.Save();
}

程序中使用connection string的部分勿需关心web.config是否加密,
public static readonly string ConnectionStringMembership = ConfigurationManager.ConnectionStrings[”myConnString”].ConnectionString;

PetShop中的OrderStrategy和System.Transactions

Filed under: 代码学习

Asynchronous Order Placement Setup Instructions

1. Add a new private queue for Pet Shop called “PSOrders”

2. Modify web.config:

a.Change the OrderStrategyClass key to OrderAsynchronous
<add key=”OrderStrategyClass” value=”PetShop.BLL.OrderAsynchronous”/>

b.Change the MachineName in the following line to your MSMQ computer name.
<add key=”OrderQueuePath” value=”FormatName:DIRECT=OS:MachineName\Private$\PSOrders”/>

3. Modify app.config in the OrderProcessor project:

Change the MachineName in the OrderQueuePath key:
<add key=”OrderQueuePath” value=”FormatName:DIRECT=OS:MachineName\Private$\PSOrders”/>

同步定单处理 和 System.Transactions
同步定单处理中的 Order.Insert() 方法使用 System.Transactions 插入一个定单并更新库存。
通过添加对 System.Transaction 命名空间的引用,并将定单插入方法和库存减少方法包装在
TransactionScope 内,

–多线程
OrderProcessor会使用多线程从Message queue中读取order,
注意,并没有任何防止竞争的机制,莫非message queue可以做到这一点?

–Transaction
OrderProcessor使用了TransactionScope,注意设置TransactionScope的
Consistent或调用TransactionScope的Complete()

System.Transactions介绍
http://blog.joycode.com/kaneboy/archive/2005/02/15/44356.aspx

Introducing System.Transactions in .NET Framework 2.0
http://msdn.microsoft.com/msdntv/episode.aspx?xml=episodes/en/20050203NETMC/manifest.xml

PetShop中的异常处理和log

Filed under: 代码学习

1.在web.config中定义要用的event log的source name.
<appSettings>
<add key=”Event Log Source” value=”.NET Pet Shop 4.0″/>
</appSettings>

2.
在Globla.asax中

private static string LOG_SOURCE = ConfigurationManager.AppSettings[”Event Log Source”];

protected void Application_Error(object sender, EventArgs e)
{
Exception x = Server.GetLastError().GetBaseException();
EventLog.WriteEntry(LOG_SOURCE, x.ToString(), EventLogEntryType.Error);
}
任何错误都会作为exception,记录在event log中.

但是此时EventLog.WriteEntry尚不可用,用则出错:
A first chance exception of type ‘System.Security.SecurityException’ occurred in mscorlib.dll
Additional information: Requested registry access is not allowed.

3.安装Event Source
可使用EventLogInstaller来安装Event Source

EventLogInstaller.Source = “.NET Pet Shop 4.0″
EventLogInstaller.Log = “Application”

或使用:
if (!System.Diagnostics.EventLog.SourceExists(”MyApp1″))
{
System.Diagnostics.EventLog.CreateEventSource(”MyApp1″, “Application”);
}

删除
EventLog.DeleteEventSource(”MyApp1″)

August 17, 2006

PetShop数据访问架构

Filed under: 代码学习

–by Aloneplayer 2006.08.17

1. IDAL
定义了各个数据实体的数据访问层的interface
如Product,对应一个
public interface IProduct
{
IList<ProductInfo> GetProductsByCategory(string category);

IList<ProductInfo> GetProductsBySearch(string[] keywords);

ProductInfo GetProduct(string productId);
}

2. Model
定义了各个数据实体类,如:
[Serializable]
public class ProductInfo
{

private string id;
private string name;
private string description;
private string image;
private string categoryId;
}

3. BLL
定义了使用数据一些函数,这些函数封装了对数据访问层函数的使用.
public class Product
{
private static readonly IProduct dal = PetShop.DALFactory.DataAccess.CreateProduct();

IList<ProductInfo> GetProductsByCategory(string category)
{
return dal.GetProductsByCategory(category);
}

IList<ProductInfo> GetProductsBySearch(string[] keywords);

ProductInfo GetProduct(string productId);
}

4. SQLServerDAL模块中定义了各个数据实体对应的数据访问层对象
每个对象都实现了IDAL层的对应Interface,如
public class Product : IProduct
{

}
每个数据访问层对象都依赖于一个封装了数据库操作的工具类,比如SQLHelper和OracleHelper,来完成对数
据库的操作.

5. DALFactory此模块中只有一个class,负责根据web.config来加载各个数据访问层对象

public sealed class DataAccess
{
private static readonly string path = ConfigurationManager.AppSettings[”WebDAL”];

public static PetShop.IDAL.IProduct CreateProduct()
{
string className = path + “.Product”;
return (PetShop.IDAL.IProduct)Assembly.Load(path).CreateInstance(className);
}

}

在web.config中WebDAL对应了当前使用了数据访问层对象所在的模块,
<add key=”WebDAL” value=”PetShop.SQLServerDAL”/>
显然,要使用其他数据库,只需要修改这个配置.

>>整个体系由数据实体(model),数据逻辑层(BLL),数据访问层构成(DAL),BLL依赖于DAL,由于数据访问层的不确定性
(可能是sql,也可能是orcal),故而将DAL拆分为IDAL和DAL,使BLL依赖于IDAL,DAL实现IDAL.
同时使用DALFactory根据配置动态生成所需DAL.

June 29, 2006

SQL 2005的安装程序

Filed under: 代码学习

今天把sql 2005的安装程序(一个hta, 很漂亮)扒开看了看,学到了

如何做mouse hover时图片和文在的淡入淡出(滤镜)

如何执行一个exe()

function onClickLinkApp(sApp)
{
var oShell = new ActiveXObject(”WScript.Shell”);
oShell.Run(sApp);
}

May 15, 2006

PetShop中的Facade

Filed under: 代码学习

在petshop中用到了HttpRuntime.Cache.Add()
其中第3个参数为dependencies,可以是null,说明此时无dependencie

petshop中的CacheDependency会根据web.confog来传递null,或dependencies
给HttpRuntime.Cache.Add()
这个变化被封装在DependencyFacade中
public static class DependencyFacade
{
private static readonly string path = ConfigurationManager.AppSettings[”CacheDependencyAssembly”];

//封装点
public static AggregateCacheDependency GetCategoryDependency()
{
if (!string.IsNullOrEmpty(path))
//这里又会用到Abstract Factory
return DependencyAccess.CreateCategoryDependency().GetDependency();
else
return null;
}
}

在使用时只会调用
// Create a AggregateCacheDependency object from the factory
AggregateCacheDependency cd = DependencyFacade.GetCategoryDependency();
// Store the output in the data cache, and Add the necessary AggregateCacheDependency object
HttpRuntime.Cache.Add(cacheKey, data, cd, DateTime.Now.AddHours(cacheDuration), Cache.NoSlidingExpiration, CacheItemPriority.High, null);
不用再判断何时需要传入null.

PetShop中的Abstract Factory

Filed under: 代码学习

在PetShop中,用户可以通过修改Web.Config来指定当前使用的数据访问层,
而不用修改任何代码,用到的核心技术为:Abstract Factory + config file

1.配置文件
<appSettings>
<add key=”WebDAL” value=”PetShop.SQLServerDAL”/>
<add key=”OrdersDAL” value=”PetShop.SQLServerDAL”/>

</appSettings>

2.在程序中有一个名为DALFactory的assemble,它只提供一个class充当Abstract Factory:
namespace PetShop.DALFactory
{

/// <summary>
/// This class is implemented following the Abstract Factory pattern to
/// create the DAL implementation
/// specified from the configuration file
/// </summary>
public sealed class DataAccess
{
//读取web.config
// Look up the DAL implementation we should be using
private static readonly string path = ConfigurationManager.AppSettings[”WebDAL”];
private static readonly string orderPath = ConfigurationManager.AppSettings[”OrdersDAL”];

private DataAccess() { }

public static PetShop.IDAL.ICategory CreateCategory()
{
string className = path + “.Category”;
return (PetShop.IDAL.ICategory)Assembly.Load(path).CreateInstance(className);
}

public static PetShop.IDAL.IInventory CreateInventory()
{
string className = path + “.Inventory”;
return (PetShop.IDAL.IInventory)Assembly.Load(path).CreateInstance(className);
}

public static PetShop.IDAL.IItem CreateItem()
{
string className = path + “.Item”;
return (PetShop.IDAL.IItem)Assembly.Load(path).CreateInstance(className);
}

public static PetShop.IDAL.IOrder CreateOrder()
{
string className = orderPath + “.Order”;
return (PetShop.IDAL.IOrder)Assembly.Load(orderPath).CreateInstance(className);
}

public static PetShop.IDAL.IProduct CreateProduct()
{
string className = path + “.Product”;
return (PetShop.IDAL.IProduct)Assembly.Load(path).CreateInstance(className);
}
}
}

以上代码逻辑基本相同:
CreateXXX先根据web.config中的信息拼接出一个classname(= config string + XXX),
然后使用CreateInstance生成实例并返回.

3. 在SQLServerDAL和OracleDAL中实现具体的class,实现对某个数据库的访问逻辑
public class Category : ICategory
{

}

这样的例子在PatShop中还有好几个.比如:
在web.config中可以个看到
<appSettings>
<add key=”ProfileDAL” value=”PetShop.SQLProfileDAL”/>

</appSettings>
代码中相应地可以找到

ProfileDALFactory
IProfileDAL
SQLProfileDAL
OracleProfileDAL

MessagingFactory
CacheDependencyFactory






















Get free blog up and running in minutes with Blogsome
Theme designed by Hadley Wickham