init lserp cs 5.0
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
using System;
|
||||
using System.Web;
|
||||
using System.Collections;
|
||||
|
||||
using Zhaizj.Framework.Data;
|
||||
using Zhaizj.Framework.Caching;
|
||||
|
||||
namespace Zhaizj.Framework.Caching {
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 应用程序范围的缓存(ORM的二级缓存)
|
||||
/// </summary>
|
||||
public class ApplicationCache : IApplicationCache {
|
||||
|
||||
/// <summary>
|
||||
/// 从二级缓存中获取值
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
public Object Get( String key ) {
|
||||
return SysCache.Get( key );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将对象放入二级缓存,如果缓存中已有此项,则替换
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="val"></param>
|
||||
public void Put( String key, Object val ) {
|
||||
SysCache.Put( key, val );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将对象放入缓存,最后一次访问之后的 minutes 分钟内,如果还没有访问,则会过期(弹性过期)
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="val"></param>
|
||||
/// <param name="minutes"></param>
|
||||
public void Put( String key, Object val, int minutes ) {
|
||||
SysCache.PutSliding( key, val, minutes * 60 );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从缓存中移除某项
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
public void Remove( String key ) {
|
||||
SysCache.Remove( key );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
using System;
|
||||
using Zhaizj.Framework.Data;
|
||||
using Zhaizj.Framework.DI;
|
||||
using Zhaizj.Framework.Web;
|
||||
|
||||
namespace Zhaizj.Framework.Caching
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// 缓存管理器
|
||||
/// </summary>
|
||||
public class CacheManager
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// 获取 ApplicationCache
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static IApplicationCache GetApplicationCache()
|
||||
{
|
||||
|
||||
|
||||
String cfgCache = DbConfig.Instance.ApplicationCacheManager;
|
||||
|
||||
if (strUtil.IsNullOrEmpty(cfgCache)) return defaultCache();
|
||||
if (ObjectContext.Instance.TypeList.ContainsKey(cfgCache) == false) return defaultCache();
|
||||
|
||||
return ObjectContext.GetByType(cfgCache) as IApplicationCache;
|
||||
|
||||
}
|
||||
|
||||
private static IApplicationCache defaultCache()
|
||||
{
|
||||
return new ApplicationCache();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
using System;
|
||||
|
||||
namespace Zhaizj.Framework.Caching {
|
||||
|
||||
public interface IApplicationCache {
|
||||
|
||||
object Get( string key );
|
||||
|
||||
void Put( string key, object val );
|
||||
void Put( string key, object val, int minutes );
|
||||
|
||||
void Remove( string key );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Web;
|
||||
using System.Web.Caching;
|
||||
|
||||
namespace Zhaizj.Framework.Caching {
|
||||
|
||||
/// <summary>
|
||||
/// .net 自带的 InMemory 缓存
|
||||
/// </summary>
|
||||
public class SysCache {
|
||||
|
||||
/// <summary>
|
||||
/// 从缓存中获取值
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
public static Object Get( String key ) {
|
||||
return HttpRuntime.Cache[key];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将对象放入缓存,如果缓存中已有此项,则替换。a)永不过期,b)优先级为 Normal,c)没有缓存依赖项
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="val"></param>
|
||||
public static void Put( String key, Object val ) {
|
||||
HttpRuntime.Cache[key] = val;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将对象放入缓存,在参数 seconds 指定的秒数之后过期
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="val"></param>
|
||||
/// <param name="seconds"></param>
|
||||
public static void Put( String key, Object val, int seconds ) {
|
||||
HttpRuntime.Cache.Insert( key, val, null, DateTime.UtcNow.AddSeconds( (double)seconds ), Cache.NoSlidingExpiration );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将对象放入缓存,在最后一次访问之后的 seconds 秒数之后过期(弹性过期)
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="val"></param>
|
||||
/// <param name="seconds"></param>
|
||||
public static void PutSliding( String key, Object val, int seconds ) {
|
||||
HttpRuntime.Cache.Insert( key, val, null, Cache.NoAbsoluteExpiration, new TimeSpan( 0, 0, seconds ) );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从缓存中移除某项
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
public static void Remove( String key ) {
|
||||
if (strUtil.HasText( key )) {
|
||||
HttpRuntime.Cache.Remove( key );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
using System;
|
||||
namespace Zhaizj.Framework.Common.AppBase {
|
||||
|
||||
/// <summary>
|
||||
/// 是否可访问的枚举(公开、好友、私人)
|
||||
/// </summary>
|
||||
public enum AccessStatus {
|
||||
Public,
|
||||
Friend,
|
||||
Private
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
namespace Zhaizj.Framework.Common.AppBase {
|
||||
|
||||
/// <summary>
|
||||
/// 关于是否可评论的枚举状态(允许、关闭、登录用户、好友)
|
||||
/// </summary>
|
||||
public class CommentCondition {
|
||||
|
||||
public static readonly int AllowAll = 0;
|
||||
public static readonly int Close = 1;
|
||||
public static readonly int LoginUser = 2;
|
||||
public static readonly int Friend = 3;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
using System;
|
||||
|
||||
namespace Zhaizj.Framework.Common.AppBase {
|
||||
|
||||
/// <summary>
|
||||
/// 注册用户的状态(待审核、删除、置顶、推荐、普通)
|
||||
/// </summary>
|
||||
public class MemberStatus {
|
||||
|
||||
public static readonly int Normal = 0;
|
||||
public static readonly int Pick = 1;
|
||||
public static readonly int Top = 2;
|
||||
public static readonly int Approving = -2;
|
||||
public static readonly int Deleted = -1;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
using System;
|
||||
|
||||
|
||||
namespace Zhaizj.Framework.Common.AppBase {
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 存储状态(普通、草稿、删除、系统删除)
|
||||
/// </summary>
|
||||
public class SaveStatus {
|
||||
|
||||
public static readonly int Normal = 0;
|
||||
public static readonly int Draft = 1;
|
||||
public static readonly int Delete = 2;
|
||||
public static readonly int SysDelete = 3;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
using System;
|
||||
|
||||
namespace Zhaizj.Framework.Common.AppBase {
|
||||
|
||||
/// <summary>
|
||||
/// 系统推荐状态(当前只推荐一种状态)
|
||||
/// </summary>
|
||||
public class SystemPickStatus {
|
||||
public static readonly int Picked = 0;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace Zhaizj.Framework.Common.AppBase {
|
||||
|
||||
/// <summary>
|
||||
/// 设置了访问控制的对象接口
|
||||
/// </summary>
|
||||
public interface IAccessStatus {
|
||||
|
||||
int AccessStatus { get; set; }
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Zhaizj.Framework.Common.AppBase {
|
||||
|
||||
/// <summary>
|
||||
/// 页面区块接口(用于门户中)
|
||||
/// </summary>
|
||||
public interface IPageSection {
|
||||
|
||||
|
||||
void AdminSectionShow( int sectionId );
|
||||
void SectionShow( int sectionId );
|
||||
|
||||
List<IPageSettingLink> GetSettingLink( int sectionId );
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
using System;
|
||||
|
||||
namespace Zhaizj.Framework.Common.AppBase {
|
||||
|
||||
/// <summary>
|
||||
/// 区块配置链接接口
|
||||
/// </summary>
|
||||
public interface IPageSettingLink {
|
||||
|
||||
String Name { get; set; }
|
||||
String Url { get; set; }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Zhaizj.Framework.Common.AppBase {
|
||||
|
||||
/// <summary>
|
||||
/// 可排序对象接口
|
||||
/// </summary>
|
||||
public interface ISort {
|
||||
int Id { get; set; }
|
||||
int OrderId { get; set; }
|
||||
void updateOrderId();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 排序工具封装
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public class SortUtil<T> where T : ISort {
|
||||
|
||||
private T data;
|
||||
private List<T> list;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="data">需要移动的对象</param>
|
||||
/// <param name="list">对象列表</param>
|
||||
public SortUtil( T data, List<T> list ) {
|
||||
this.data = data;
|
||||
this.list = list;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取经过排序的列表
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public List<T> GetOrderedList() {
|
||||
return this.list;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 先前移动
|
||||
/// </summary>
|
||||
public void MoveUp() {
|
||||
|
||||
int dataId = data.Id;
|
||||
|
||||
for (int i = 0; i < list.Count; i++) {
|
||||
|
||||
T t = list[i];
|
||||
int orderId = list.Count - i;
|
||||
|
||||
if (t.Id == dataId && i == 0) continue;
|
||||
|
||||
if (isPrevData( i, dataId )) {
|
||||
t.OrderId = orderId - 1;
|
||||
t.updateOrderId();
|
||||
}
|
||||
else if (t.Id == dataId) {
|
||||
t.OrderId = orderId + 1;
|
||||
t.updateOrderId();
|
||||
}
|
||||
else if (t.OrderId != orderId) {
|
||||
t.OrderId = orderId;
|
||||
t.updateOrderId();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 先后移动
|
||||
/// </summary>
|
||||
public void MoveDown() {
|
||||
|
||||
int dataId = data.Id;
|
||||
|
||||
for (int i = 0; i < list.Count; i++) {
|
||||
|
||||
T t = list[i];
|
||||
int orderId = list.Count - i;
|
||||
|
||||
if (t.Id == dataId && i == list.Count - 1) continue;
|
||||
|
||||
if (isNextData( i, dataId )) {
|
||||
t.OrderId = orderId + 1;
|
||||
t.updateOrderId();
|
||||
}
|
||||
else if (t.Id == dataId) {
|
||||
t.OrderId = orderId - 1;
|
||||
t.updateOrderId();
|
||||
}
|
||||
else if (t.OrderId != orderId) {
|
||||
t.OrderId = orderId;
|
||||
t.updateOrderId();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private Boolean isNextData( int i, int dataId ) {
|
||||
if (i == 0) return false;
|
||||
if (list[i - 1].Id == dataId) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
private Boolean isPrevData( int i, int dataId ) {
|
||||
if (i > list.Count - 2) return false;
|
||||
if (list[i + 1].Id == dataId) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Zhaizj.Framework.Common {
|
||||
|
||||
/// <summary>
|
||||
/// 常用的固定字符串
|
||||
/// </summary>
|
||||
public class ConstString {
|
||||
|
||||
/// <summary>
|
||||
/// 网站类型全名
|
||||
/// </summary>
|
||||
public static readonly String SiteTypeFullName = "Zhaizj.Framework.Members.Sites.Domain.Site";
|
||||
|
||||
/// <summary>
|
||||
/// 用户类型全名
|
||||
/// </summary>
|
||||
public static readonly String UserTypeFullName = "Zhaizj.Framework.Members.Users.Domain.User";
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Zhaizj.Framework.Common {
|
||||
|
||||
/// <summary>
|
||||
/// 通用绑定对象接口
|
||||
/// </summary>
|
||||
public interface IBinderValue {
|
||||
|
||||
String CreatorName { get; set; }
|
||||
String CreatorLink { get; set; }
|
||||
String CreatorPic { get; set; }
|
||||
|
||||
String Category { get; set; }
|
||||
|
||||
String Title { get; set; }
|
||||
String Link { get; set; }
|
||||
String Content { get; set; }
|
||||
String Summary { get; set; }
|
||||
|
||||
String PicUrl { get; set; }
|
||||
|
||||
DateTime Created { get; set; }
|
||||
int Replies { get; set; }
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
using System;
|
||||
|
||||
namespace Zhaizj.Framework.Common {
|
||||
|
||||
/// <summary>
|
||||
/// 需要统计点击数的对象接口
|
||||
/// </summary>
|
||||
public interface IHits {
|
||||
int Id { get; set; }
|
||||
int Hits { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
using System;
|
||||
|
||||
namespace Zhaizj.Framework.Common {
|
||||
|
||||
/// <summary>
|
||||
/// 需要被分享的数据接口
|
||||
/// </summary>
|
||||
public interface IShareData {
|
||||
|
||||
int Id { get; set; }
|
||||
|
||||
IShareInfo GetShareInfo();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace Zhaizj.Framework.Common {
|
||||
|
||||
/// <summary>
|
||||
/// 分享工具的接口
|
||||
/// </summary>
|
||||
public interface IShareInfo {
|
||||
|
||||
IEntity GetTarget();
|
||||
|
||||
String GetShareTitleTemplate();
|
||||
String GetShareTitleData();
|
||||
|
||||
String GetShareBodyTemplate();
|
||||
String GetShareBodyData( String dataLink );
|
||||
|
||||
void addNotification( String creator, String creatorLink );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Zhaizj.Framework.Common {
|
||||
|
||||
/// <summary>
|
||||
/// 通用绑定对象
|
||||
/// </summary>
|
||||
public class ItemValue : IBinderValue {
|
||||
|
||||
public String CreatorName { get; set; }
|
||||
public String CreatorLink { get; set; }
|
||||
public String CreatorPic { get; set; }
|
||||
|
||||
public String Category { get; set; }
|
||||
|
||||
public String Title { get; set; }
|
||||
public String Link { get; set; }
|
||||
public String Content { get; set; }
|
||||
public String Summary { get; set; }
|
||||
public String PicUrl { get; set; }
|
||||
|
||||
public DateTime Created { get; set; }
|
||||
public int Replies { get; set; }
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
|
||||
namespace Zhaizj.Framework.Common {
|
||||
|
||||
/// <summary>
|
||||
/// 用户登录状态保持时间
|
||||
/// </summary>
|
||||
public enum LoginTime {
|
||||
Forever,
|
||||
Never,
|
||||
OneYear,
|
||||
OneMonth,
|
||||
OneWeek
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,229 @@
|
||||
/*
|
||||
* Copyright 2010 www.wojilu.com
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using wojilu.Web.Context;
|
||||
using wojilu.Web;
|
||||
using wojilu.Web.Mvc;
|
||||
|
||||
namespace wojilu.Common.Onlines {
|
||||
|
||||
/// <summary>
|
||||
/// 在线管理器
|
||||
/// </summary>
|
||||
public class OnlineManager {
|
||||
|
||||
|
||||
private static readonly ILog logger = LogManager.GetLogger( typeof( OnlineManager ) );
|
||||
|
||||
public static void Refresh( MvcContext ctx ) {
|
||||
Boolean isSpider = isAgentSpider( ctx );
|
||||
if (isSpider) return;
|
||||
|
||||
UpdateOnline( ctx );
|
||||
|
||||
DeleteTimeoutVisitor( ctx );// TODO job异步处理
|
||||
UpdateMaxOnline( ctx );// TODO job异步处理
|
||||
|
||||
CountOnlineData( ctx );// 在UpdateOnline时候即算出,不需要额外计算
|
||||
|
||||
}
|
||||
|
||||
#region refresh private
|
||||
|
||||
private static Boolean isAgentSpider( MvcContext ctx ) {
|
||||
|
||||
String agent = ctx.web.ClientAgent;
|
||||
if (agent == null) return true;
|
||||
|
||||
foreach (String spiderName in config.Instance.Site.Spider) {
|
||||
|
||||
if (agent.ToLower().IndexOf( spiderName.ToLower() ) >= 0) {
|
||||
// TODO 记录spider在线情况
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void CountOnlineData( MvcContext ctx ) {
|
||||
List<OnlineUser> allVisitors = cdb.findAll<OnlineUser>();
|
||||
OnlineStats.Instance.Count = allVisitors.Count;
|
||||
int memberCount = 0;
|
||||
for (int i = 0; i < allVisitors.Count; i++) {
|
||||
OnlineUser online = allVisitors[i] as OnlineUser;
|
||||
if (online == null) continue;
|
||||
if (online.UserId > 0) {
|
||||
memberCount++;
|
||||
}
|
||||
}
|
||||
OnlineStats.Instance.MemberCount = memberCount;
|
||||
OnlineStats.Instance.GuestCount = OnlineStats.Instance.Count - OnlineStats.Instance.MemberCount;
|
||||
}
|
||||
|
||||
|
||||
private static void UpdateOnline( MvcContext ctx ) {
|
||||
|
||||
|
||||
String sid = getSessionId( ctx );
|
||||
List<OnlineUser> result = cdb.findByName<OnlineUser>( sid );
|
||||
Boolean isNew = (result.Count == 0 ? true : false);
|
||||
|
||||
if (isNew) {
|
||||
OnlineUser myOnline = new OnlineUser();
|
||||
myOnline.Name = sid;
|
||||
myOnline.StartTime = DateTime.Now;
|
||||
|
||||
populateOnline( myOnline, ctx );
|
||||
|
||||
Dictionary<String, Object> dic = getIndexMap( myOnline );
|
||||
myOnline.insertByIndex( dic );
|
||||
|
||||
|
||||
}
|
||||
else {
|
||||
OnlineUser myOnline = result[0];
|
||||
populateOnline( myOnline, ctx );
|
||||
Dictionary<String, Object> dic = getIndexMap( myOnline );
|
||||
myOnline.updateByIndex( dic );
|
||||
|
||||
}
|
||||
|
||||
// 检查是否有同名的登录用户
|
||||
if ( ctx.viewer != null && ctx.viewer.IsLogin) {
|
||||
|
||||
List<OnlineUser> sameUsers = cdb.findBy<OnlineUser>( "UserName", ctx.viewer.obj.Name );
|
||||
if (sameUsers.Count > 1) {
|
||||
foreach (OnlineUser u in sameUsers) {
|
||||
if (u.Name == sid) continue;
|
||||
cdb.delete( u );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static Dictionary<String, Object> getIndexMap( OnlineUser myOnline ) {
|
||||
Dictionary<String, Object> dic = new Dictionary<String, Object>();
|
||||
dic.Add( "Name", myOnline.Name );
|
||||
dic.Add( "UserName", myOnline.UserName );
|
||||
return dic;
|
||||
}
|
||||
|
||||
private static void populateOnline( OnlineUser myOnline, MvcContext ctx ) {
|
||||
|
||||
myOnline.Role = String.Empty;
|
||||
myOnline.Ip = ctx.Ip;
|
||||
myOnline.TrueIp = ctx.Ip;
|
||||
myOnline.Agent = strUtil.CutString( ctx.web.ClientAgent, 240 );
|
||||
|
||||
|
||||
if (ctx.viewer != null && ctx.viewer.obj != null) {
|
||||
|
||||
myOnline.UserName = ctx.viewer.obj.Name;
|
||||
myOnline.UserId = ctx.viewer.Id;
|
||||
myOnline.UserUrl = Link.ToMember( ctx.viewer.obj );
|
||||
myOnline.UserPicUrl = ctx.viewer.obj.PicSmall;
|
||||
}
|
||||
else
|
||||
myOnline.UserName = "guest";
|
||||
|
||||
if (ctx.owner != null && ctx.owner.obj != null)
|
||||
myOnline.Target = ctx.owner.obj.Name;
|
||||
|
||||
myOnline.IsHidden = 0;
|
||||
|
||||
String referrer = "";
|
||||
if (ctx.web.PathReferrer != null) referrer = ctx.web.PathReferrer;
|
||||
myOnline.Referrer = referrer;
|
||||
|
||||
myOnline.LastActive = DateTime.Now;
|
||||
myOnline.Location = getLocation( ctx );
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static void DeleteTimeoutVisitor( MvcContext ctx ) {
|
||||
List<OnlineUser> allVisitors = cdb.findAll<OnlineUser>();
|
||||
for (int i = 0; i < allVisitors.Count; i++) {
|
||||
|
||||
OnlineUser online = allVisitors[i] as OnlineUser;
|
||||
if (online == null) continue;
|
||||
TimeSpan span = DateTime.Now.Subtract( online.LastActive );
|
||||
try {
|
||||
if (span.TotalMinutes > 20) online.delete();
|
||||
}
|
||||
catch (Exception ex) {
|
||||
logger.Error( "DeleteTimeoutVisitor:" + ex );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void UpdateMaxOnline( MvcContext ctx ) {
|
||||
if (OnlineStats.Instance.Count > config.Instance.Site.MaxOnline) {
|
||||
|
||||
config.Instance.Site.MaxOnline = OnlineStats.Instance.Count;
|
||||
config.Instance.Site.MaxOnlineTime = DateTime.Now;
|
||||
|
||||
config.Instance.Site.Update( "MaxOnline", OnlineStats.Instance.Count );
|
||||
config.Instance.Site.Update( "MaxOnlineTime", DateTime.Now );
|
||||
}
|
||||
|
||||
OnlineStats.Instance.MaxCount = config.Instance.Site.MaxOnline;
|
||||
OnlineStats.Instance.MaxTime = config.Instance.Site.MaxOnlineTime;
|
||||
}
|
||||
|
||||
private static String getSessionId( MvcContext ctx ) {
|
||||
|
||||
String sidstring = "sessionId";
|
||||
|
||||
String cookieValue = ctx.web.CookieGet( sidstring );
|
||||
|
||||
if (strUtil.HasText( cookieValue )) {
|
||||
|
||||
return cookieValue;
|
||||
}
|
||||
|
||||
else {
|
||||
return setGuestSessionId( ctx, sidstring );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private static String setGuestSessionId( MvcContext ctx, String sidstring ) {
|
||||
String guidSessionId = getGuidString();
|
||||
ctx.web.CookieSet( sidstring, guidSessionId );
|
||||
return guidSessionId;
|
||||
}
|
||||
|
||||
|
||||
private static String getGuidString() {
|
||||
return Guid.NewGuid().ToString().Replace( "-", "" );
|
||||
}
|
||||
|
||||
private static String getLocation( MvcContext ctx ) {
|
||||
String result = ctx.url.PathAndQuery;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright 2010 www.wojilu.com
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using wojilu.Web.Context;
|
||||
using wojilu.Web;
|
||||
using wojilu.Web.Mvc;
|
||||
|
||||
namespace wojilu.Common.Onlines {
|
||||
|
||||
/// <summary>
|
||||
/// 提供在线状态的各类数据
|
||||
/// </summary>
|
||||
public class OnlineService {
|
||||
|
||||
|
||||
|
||||
public static List<OnlineUser> GetAll() {
|
||||
List<OnlineUser> all = cdb.findAll<OnlineUser>();
|
||||
all.Sort();
|
||||
return all;
|
||||
}
|
||||
|
||||
public static List<OnlineUser> GetGuest() {
|
||||
List<OnlineUser> all = GetAll();
|
||||
|
||||
List<OnlineUser> allUsers = new List<OnlineUser>();
|
||||
foreach (OnlineUser info in all) {
|
||||
if (info.UserId <= 0) allUsers.Add( info );
|
||||
}
|
||||
|
||||
return allUsers;
|
||||
}
|
||||
|
||||
public static List<OnlineUser> GetLoggerUser() {
|
||||
|
||||
List<OnlineUser> all = GetAll();
|
||||
|
||||
List<OnlineUser> allUsers = new List<OnlineUser>();
|
||||
foreach (OnlineUser info in all) {
|
||||
if (info.UserId > 0) allUsers.Add( info );
|
||||
}
|
||||
|
||||
return allUsers;
|
||||
}
|
||||
|
||||
public static List<OnlineUser> GetRecent( int count ) {
|
||||
|
||||
List<OnlineUser> all = GetAll();
|
||||
|
||||
int icount = 1;
|
||||
List<OnlineUser> results = new List<OnlineUser>();
|
||||
foreach (OnlineUser info in all) {
|
||||
if (icount > count) break;
|
||||
if (info.UserId > 0) {
|
||||
results.Add( info );
|
||||
icount++;
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
public static List<OnlineUser> GetRecentAll( int count ) {
|
||||
|
||||
List<OnlineUser> all = GetAll();
|
||||
|
||||
int icount = 1;
|
||||
List<OnlineUser> results = new List<OnlineUser>();
|
||||
foreach (OnlineUser info in all) {
|
||||
if (icount > count) break;
|
||||
|
||||
results.Add( info );
|
||||
icount++;
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2010 www.wojilu.com
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace wojilu.Common.Onlines {
|
||||
|
||||
/// <summary>
|
||||
/// ÔÚÏß״̬Êý¾Ý
|
||||
/// </summary>
|
||||
public class OnlineStats {
|
||||
|
||||
private OnlineStats() { }
|
||||
|
||||
public int Count { get; set; }
|
||||
public int GuestCount { get; set; }
|
||||
public int MemberCount { get; set; }
|
||||
|
||||
public int MaxCount { get; set; }
|
||||
public DateTime MaxTime { get; set; }
|
||||
|
||||
public static OnlineStats Instance = new OnlineStats();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2010 www.wojilu.com
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
using wojilu.Data;
|
||||
using wojilu.ORM;
|
||||
|
||||
namespace wojilu.Common.Onlines {
|
||||
|
||||
/// <summary>
|
||||
/// ÔÚÏßÓû§ÐÅÏ¢·â×°
|
||||
/// </summary>
|
||||
[NotSave]
|
||||
public class OnlineUser : CacheObject, IComparable {
|
||||
|
||||
public int UserId { get; set; }
|
||||
public String UserName { get; set; }
|
||||
public String UserUrl { get; set; }
|
||||
public String UserPicUrl { get; set; }
|
||||
|
||||
public String Role { get; set; }
|
||||
|
||||
public int IsHidden { get; set; }
|
||||
|
||||
public String Location { get; set; }
|
||||
public String Referrer { get; set; }
|
||||
public String Agent { get; set; }
|
||||
|
||||
public DateTime StartTime { get; set; }
|
||||
public DateTime LastActive { get; set; }
|
||||
|
||||
public String Target { get; set; }
|
||||
|
||||
public String Ip { get; set; }
|
||||
public String TrueIp { get; set; }
|
||||
|
||||
|
||||
public int CompareTo( Object obj ) {
|
||||
OnlineUser target = obj as OnlineUser;
|
||||
if (target.LastActive > this.LastActive) return 1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using wojilu.Web.Jobs;
|
||||
|
||||
namespace wojilu.Common.Onlines {
|
||||
|
||||
|
||||
public class OnlineJob : IWebJobItem {
|
||||
|
||||
private static readonly ILog logger = LogManager.GetLogger( typeof( OnlineJob ) );
|
||||
|
||||
public void Execute() {
|
||||
deleteTimeoutVisitor();
|
||||
updateMaxOnline();
|
||||
}
|
||||
|
||||
public void End() {
|
||||
}
|
||||
|
||||
private static void deleteTimeoutVisitor() {
|
||||
|
||||
logger.Info( "---------------deleteTimeoutVisitor---------------" );
|
||||
|
||||
List<OnlineUser> allVisitors = cdb.findAll<OnlineUser>();
|
||||
for (int i = 0; i < allVisitors.Count; i++) {
|
||||
|
||||
OnlineUser online = allVisitors[i] as OnlineUser;
|
||||
if (online == null) continue;
|
||||
TimeSpan span = DateTime.Now.Subtract( online.LastActive );
|
||||
try {
|
||||
if (span.TotalMinutes > 20) online.delete();
|
||||
}
|
||||
catch (Exception ex) {
|
||||
logger.Error( "DeleteTimeoutVisitor:" + ex );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private static void updateMaxOnline() {
|
||||
|
||||
logger.Info( "---------------updateMaxOnline---------------" );
|
||||
|
||||
|
||||
if (OnlineStats.Instance.Count <= config.Instance.Site.MaxOnline) return;
|
||||
|
||||
config.Instance.Site.MaxOnline = OnlineStats.Instance.Count;
|
||||
config.Instance.Site.MaxOnlineTime = DateTime.Now;
|
||||
|
||||
config.Instance.Site.Update( "MaxOnline", OnlineStats.Instance.Count );
|
||||
config.Instance.Site.Update( "MaxOnlineTime", DateTime.Now );
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,169 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Zhaizj.Framework.Web.Context;
|
||||
using Zhaizj.Framework.Web;
|
||||
using Zhaizj.Framework.Web.Mvc;
|
||||
|
||||
namespace Zhaizj.Framework.Common.Onlines {
|
||||
|
||||
/// <summary>
|
||||
/// 在线管理器
|
||||
/// </summary>
|
||||
public class OnlineManager {
|
||||
|
||||
private static readonly ILog logger = LogManager.GetLogger( typeof( OnlineManager ) );
|
||||
|
||||
public static void Refresh( MvcContext ctx ) {
|
||||
|
||||
if (isAgentSpider( ctx )) return;
|
||||
|
||||
String sid = getSessionId( ctx );
|
||||
List<OnlineUser> users = cdb.findByName<OnlineUser>( sid );
|
||||
Boolean isNew = (users.Count == 0 ? true : false);
|
||||
|
||||
if (isNew) {
|
||||
addNewVisitor( ctx, sid );
|
||||
}
|
||||
else {
|
||||
updateVisitor( ctx, users[0] );
|
||||
}
|
||||
|
||||
|
||||
deleteSameUser( ctx, sid );
|
||||
}
|
||||
|
||||
|
||||
private static Boolean isAgentSpider( MvcContext ctx ) {
|
||||
|
||||
String agent = ctx.web.ClientAgent;
|
||||
if (agent == null) return true;
|
||||
|
||||
foreach (String spiderName in config.Instance.Site.Spider) {
|
||||
|
||||
if (agent.ToLower().IndexOf( spiderName.ToLower() ) >= 0) {
|
||||
return true; // TODO 记录spider在线情况
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
private static void updateVisitor( MvcContext ctx, OnlineUser myOnline ) {
|
||||
populateOnline( myOnline, ctx );
|
||||
Dictionary<String, Object> dic = getIndexMap( myOnline );
|
||||
myOnline.updateByIndex( dic );
|
||||
}
|
||||
|
||||
private static void addNewVisitor( MvcContext ctx, String sid ) {
|
||||
OnlineUser visitor = new OnlineUser();
|
||||
visitor.Name = sid;
|
||||
visitor.StartTime = DateTime.Now;
|
||||
|
||||
populateOnline( visitor, ctx );
|
||||
|
||||
Dictionary<String, Object> dic = getIndexMap( visitor );
|
||||
visitor.insertByIndex( dic );
|
||||
|
||||
|
||||
if (ctx.viewer != null && ctx.viewer.Id > 0) OnlineStats.Instance.AddMemberCount();
|
||||
}
|
||||
|
||||
// 检查是否有同名的登录用户
|
||||
private static void deleteSameUser( MvcContext ctx, String sid ) {
|
||||
|
||||
if (ctx.viewer == null) return;
|
||||
if (ctx.viewer.Id <= 0) return;
|
||||
|
||||
List<OnlineUser> sameUsers = cdb.findBy<OnlineUser>( "UserName", ctx.viewer.obj.Name );
|
||||
if (sameUsers.Count == 0) return;
|
||||
|
||||
foreach (OnlineUser u in sameUsers) {
|
||||
if (u.Name == sid) continue;
|
||||
cdb.delete( u );
|
||||
OnlineStats.Instance.SubtractMemberCount();
|
||||
}
|
||||
}
|
||||
|
||||
private static Dictionary<String, Object> getIndexMap( OnlineUser visitor ) {
|
||||
Dictionary<String, Object> dic = new Dictionary<String, Object>();
|
||||
dic.Add( "Name", visitor.Name );
|
||||
dic.Add( "UserName", visitor.UserName );
|
||||
return dic;
|
||||
}
|
||||
|
||||
private static void populateOnline( OnlineUser visitor, MvcContext ctx ) {
|
||||
|
||||
visitor.Role = "";
|
||||
visitor.Ip = ctx.Ip;
|
||||
visitor.TrueIp = ctx.Ip;
|
||||
visitor.Agent = strUtil.CutString( ctx.web.ClientAgent, 240 );
|
||||
|
||||
if (ctx.viewer != null && ctx.viewer.obj != null) {
|
||||
|
||||
visitor.UserName = ctx.viewer.obj.Name;
|
||||
visitor.UserId = ctx.viewer.Id;
|
||||
visitor.UserUrl = Link.ToMember( ctx.viewer.obj );
|
||||
visitor.UserPicUrl = ctx.viewer.obj.PicSmall;
|
||||
}
|
||||
else { // 游客
|
||||
|
||||
visitor.UserName = "guest";
|
||||
visitor.UserId = 0;
|
||||
visitor.UserUrl = "";
|
||||
visitor.UserPicUrl = "";
|
||||
|
||||
}
|
||||
|
||||
if (ctx.owner != null && ctx.owner.obj != null)
|
||||
visitor.Target = ctx.owner.obj.Name;
|
||||
|
||||
visitor.IsHidden = 0;
|
||||
|
||||
String referrer = "";
|
||||
if (ctx.web.PathReferrer != null) referrer = ctx.web.PathReferrer;
|
||||
visitor.Referrer = referrer;
|
||||
|
||||
visitor.LastActive = DateTime.Now;
|
||||
visitor.Location = getLocation( ctx );
|
||||
}
|
||||
|
||||
|
||||
private static String getSessionId( MvcContext ctx ) {
|
||||
|
||||
String sidstring = "sessionId";
|
||||
|
||||
String cookieValue = ctx.web.CookieGet( sidstring );
|
||||
|
||||
if (strUtil.HasText( cookieValue )) {
|
||||
|
||||
return cookieValue;
|
||||
}
|
||||
|
||||
else {
|
||||
return setGuestSessionId( ctx, sidstring );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private static String setGuestSessionId( MvcContext ctx, String sidstring ) {
|
||||
String guidSessionId = getGuidString();
|
||||
ctx.web.CookieSet( sidstring, guidSessionId );
|
||||
return guidSessionId;
|
||||
}
|
||||
|
||||
|
||||
private static String getGuidString() {
|
||||
return Guid.NewGuid().ToString().Replace( "-", "" );
|
||||
}
|
||||
|
||||
// TODO 精确描述当前位置
|
||||
private static String getLocation( MvcContext ctx ) {
|
||||
String result = ctx.url.PathAndQuery;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Zhaizj.Framework.Web.Context;
|
||||
using Zhaizj.Framework.Web;
|
||||
using Zhaizj.Framework.Web.Mvc;
|
||||
|
||||
namespace Zhaizj.Framework.Common.Onlines {
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 提供在线状态的各类数据
|
||||
/// </summary>
|
||||
public class OnlineService {
|
||||
|
||||
public static List<OnlineUser> GetAll() {
|
||||
|
||||
List<OnlineUser> all = cdb.findAll<OnlineUser>();
|
||||
all.Sort();
|
||||
return all;
|
||||
}
|
||||
|
||||
public static List<OnlineUser> GetGuest() {
|
||||
|
||||
List<OnlineUser> all = cdb.findAll<OnlineUser>();
|
||||
|
||||
List<OnlineUser> allUsers = new List<OnlineUser>();
|
||||
foreach (OnlineUser info in all) {
|
||||
if (info.UserId <= 0) allUsers.Add( info );
|
||||
}
|
||||
|
||||
allUsers.Sort();
|
||||
|
||||
return allUsers;
|
||||
}
|
||||
|
||||
public static List<OnlineUser> GetLoggerUser() {
|
||||
|
||||
List<OnlineUser> all = cdb.findAll<OnlineUser>();
|
||||
|
||||
List<OnlineUser> allUsers = new List<OnlineUser>();
|
||||
foreach (OnlineUser info in all) {
|
||||
if (info.UserId > 0) allUsers.Add( info );
|
||||
}
|
||||
|
||||
allUsers.Sort();
|
||||
|
||||
return allUsers;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 最新登录用户
|
||||
/// </summary>
|
||||
/// <param name="count"></param>
|
||||
/// <returns></returns>
|
||||
public static List<OnlineUser> GetRecent( int count ) {
|
||||
|
||||
List<OnlineUser> all = cdb.findAll<OnlineUser>();
|
||||
|
||||
int icount = 1;
|
||||
List<OnlineUser> results = new List<OnlineUser>();
|
||||
foreach (OnlineUser info in all) {
|
||||
if (icount > count) break;
|
||||
if (info.UserId > 0) {
|
||||
results.Add( info );
|
||||
icount++;
|
||||
}
|
||||
}
|
||||
|
||||
results.Sort();
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 最新所有用户
|
||||
/// </summary>
|
||||
/// <param name="count"></param>
|
||||
/// <returns></returns>
|
||||
public static List<OnlineUser> GetRecentAll( int count ) {
|
||||
|
||||
List<OnlineUser> all = cdb.findAll<OnlineUser>();
|
||||
|
||||
int icount = 1;
|
||||
List<OnlineUser> results = new List<OnlineUser>();
|
||||
foreach (OnlineUser info in all) {
|
||||
if (icount > count) break;
|
||||
|
||||
results.Add( info );
|
||||
icount++;
|
||||
}
|
||||
|
||||
results.Sort();
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Zhaizj.Framework.Common.Onlines {
|
||||
|
||||
/// <summary>
|
||||
/// 在线状态数据
|
||||
/// </summary>
|
||||
public class OnlineStats {
|
||||
|
||||
public static readonly OnlineStats Instance = new OnlineStats();
|
||||
private object objLock = new object();
|
||||
|
||||
private OnlineStats() { }
|
||||
|
||||
public int Count {
|
||||
get { return cdb.findAll<OnlineUser>().Count; }
|
||||
}
|
||||
|
||||
public int GuestCount {
|
||||
get { return this.Count - this.MemberCount; }
|
||||
}
|
||||
|
||||
private int _memberCount;
|
||||
|
||||
public int MemberCount {
|
||||
get { return _memberCount; }
|
||||
}
|
||||
|
||||
// 1) 新用户登录的时候(+1)
|
||||
// 2) 用户(+1)->游客(注销会-1)->用户(登录会+1)
|
||||
public void AddMemberCount() {
|
||||
|
||||
lock (objLock) {
|
||||
_memberCount = _memberCount + 1;
|
||||
}
|
||||
}
|
||||
|
||||
// 1) 注销的时候-1
|
||||
// 2) 用其他客户端,同一账号登录-1
|
||||
// 3) 超时,由系统自动清除-1
|
||||
public void SubtractMemberCount() {
|
||||
|
||||
lock (objLock) {
|
||||
_memberCount = _memberCount - 1;
|
||||
if (_memberCount < 0) _memberCount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public void ReCount() {
|
||||
|
||||
lock (objLock) {
|
||||
|
||||
_memberCount = OnlineService.GetLoggerUser().Count;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public int MaxCount {
|
||||
get { return config.Instance.Site.MaxOnline; }
|
||||
}
|
||||
public DateTime MaxTime {
|
||||
get { return config.Instance.Site.MaxOnlineTime; }
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
using Zhaizj.Framework.Data;
|
||||
using Zhaizj.Framework.ORM;
|
||||
|
||||
namespace Zhaizj.Framework.Common.Onlines {
|
||||
|
||||
/// <summary>
|
||||
/// ÔÚÏßÓû§ÐÅÏ¢·â×°
|
||||
/// </summary>
|
||||
[NotSave]
|
||||
public class OnlineUser : CacheObject, IComparable {
|
||||
|
||||
public int UserId { get; set; }
|
||||
public String UserName { get; set; }
|
||||
public String UserUrl { get; set; }
|
||||
public String UserPicUrl { get; set; }
|
||||
|
||||
public String Role { get; set; }
|
||||
|
||||
public int IsHidden { get; set; }
|
||||
|
||||
public String Location { get; set; }
|
||||
public String Referrer { get; set; }
|
||||
public String Agent { get; set; }
|
||||
|
||||
public DateTime StartTime { get; set; }
|
||||
public DateTime LastActive { get; set; }
|
||||
|
||||
public String Target { get; set; }
|
||||
|
||||
public String Ip { get; set; }
|
||||
public String TrueIp { get; set; }
|
||||
|
||||
|
||||
public int CompareTo( Object obj ) {
|
||||
OnlineUser target = obj as OnlineUser;
|
||||
if (target.LastActive > this.LastActive) return 1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,273 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Zhaizj.Framework.Common.Resource {
|
||||
|
||||
/// <summary>
|
||||
/// 各类常用基础数据列表(省份、性别、时间、身高、婚姻、血型、星座等)
|
||||
/// </summary>
|
||||
public class AppResource {
|
||||
|
||||
/// <summary>
|
||||
/// 体型
|
||||
/// </summary>
|
||||
public static PropertyCollection Body = GetPropertyList( "member_body" );
|
||||
|
||||
/// <summary>
|
||||
/// 其他用户联系我的条件
|
||||
/// </summary>
|
||||
public static PropertyCollection ContactCondition = GetPropertyList( "member_contactcondition" );
|
||||
|
||||
/// <summary>
|
||||
/// email通知状态(启用/禁用)
|
||||
/// </summary>
|
||||
public static PropertyCollection EmailNotify = GetPropertyList( "member_emailnotify" );
|
||||
|
||||
/// <summary>
|
||||
/// 性别(保密/男/女)
|
||||
/// </summary>
|
||||
public static PropertyCollection Gender = GetPropertyList( "member_gender" );
|
||||
|
||||
/// <summary>
|
||||
/// 头发颜色
|
||||
/// </summary>
|
||||
public static PropertyCollection Hair = GetPropertyList( "member_hair" );
|
||||
|
||||
/// <summary>
|
||||
/// 身高选项
|
||||
/// </summary>
|
||||
public static PropertyCollection Height = getHeightPropertyList();
|
||||
|
||||
/// <summary>
|
||||
/// 省份
|
||||
/// </summary>
|
||||
public static PropertyCollection Province = GetPropertyList( "province" );
|
||||
|
||||
/// <summary>
|
||||
/// 注册目的
|
||||
/// </summary>
|
||||
public static PropertyCollection Purpose = GetPropertyList( "member_regpurpose" );
|
||||
|
||||
/// <summary>
|
||||
/// 婚姻状况
|
||||
/// </summary>
|
||||
public static PropertyCollection Relationship = GetPropertyList( "member_relationship" );
|
||||
|
||||
/// <summary>
|
||||
/// 性取向
|
||||
/// </summary>
|
||||
public static PropertyCollection Sexuality = GetPropertyList( "member_sexuality" );
|
||||
|
||||
/// <summary>
|
||||
/// 睡眠习惯
|
||||
/// </summary>
|
||||
public static PropertyCollection Sleeping = GetPropertyList( "member_sleeping" );
|
||||
|
||||
/// <summary>
|
||||
/// 吸烟爱好
|
||||
/// </summary>
|
||||
public static PropertyCollection Smoking = GetPropertyList( "member_smoking" );
|
||||
|
||||
/// <summary>
|
||||
/// 体重
|
||||
/// </summary>
|
||||
public static PropertyCollection Weight = getWeightPropertyList();
|
||||
|
||||
/// <summary>
|
||||
/// 血型
|
||||
/// </summary>
|
||||
public static PropertyCollection Blood = GetPropertyList( "member_blood" );
|
||||
|
||||
/// <summary>
|
||||
/// 星座
|
||||
/// </summary>
|
||||
public static PropertyCollection Zodiac = GetPropertyList( "member_zodiac" );
|
||||
|
||||
/// <summary>
|
||||
/// 时间列表
|
||||
/// </summary>
|
||||
public static String[] Time = getOneDayTime();
|
||||
|
||||
/// <summary>
|
||||
/// 学历
|
||||
/// </summary>
|
||||
public static PropertyCollection Degree = GetPropertyList( "degree_list" );
|
||||
|
||||
private static PropertyCollection getHeightPropertyList() {
|
||||
PropertyCollection propertys = new PropertyCollection();
|
||||
propertys.Add( new PropertyItem( lang.get( "plsSelect" ), 0 ) );
|
||||
for (int i = 120; i < 221; i++) {
|
||||
propertys.Add( new PropertyItem( i + " cm", i ) );
|
||||
}
|
||||
return propertys;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取语言包里存储的键值对列表(用于自定义扩展)
|
||||
/// </summary>
|
||||
/// <param name="langItemName">语言key</param>
|
||||
/// <returns></returns>
|
||||
public static PropertyCollection GetPropertyList( String langItemName ) {
|
||||
|
||||
PropertyCollection propertys = new PropertyCollection();
|
||||
String str = lang.get( langItemName );
|
||||
if (strUtil.IsNullOrEmpty( str )) return propertys;
|
||||
|
||||
String[] strArray = str.Split( new char[] { '/' } );
|
||||
foreach (String item in strArray) {
|
||||
if (strUtil.IsNullOrEmpty( item )) continue;
|
||||
String[] arrPair = item.Split( new char[] { '-' } );
|
||||
if (arrPair.Length != 2) continue;
|
||||
String name = arrPair[0].Trim();
|
||||
int val = cvt.ToInt( arrPair[1] );
|
||||
propertys.Add( new PropertyItem( name, val ) );
|
||||
}
|
||||
|
||||
return propertys;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据值获取省份名称
|
||||
/// </summary>
|
||||
/// <param name="provinceId"></param>
|
||||
/// <returns></returns>
|
||||
public static PropertyItem GetProvince( int provinceId ) {
|
||||
PropertyCollection province = Province;
|
||||
foreach (PropertyItem item in province) {
|
||||
if (item.Value == provinceId) return item;
|
||||
}
|
||||
return new PropertyItem( "", provinceId );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据项值,获取项的名称
|
||||
/// </summary>
|
||||
/// <param name="langKey">语言包中的key</param>
|
||||
/// <param name="itemId">项值</param>
|
||||
/// <returns>项的名称</returns>
|
||||
public static String GetItemName( String langKey, int itemId ) {
|
||||
PropertyCollection list = GetPropertyList( langKey );
|
||||
foreach (PropertyItem item in list) {
|
||||
if (item.Value == itemId) return item.Name;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static PropertyCollection getWeightPropertyList() {
|
||||
PropertyCollection propertys = new PropertyCollection();
|
||||
propertys.Add( new PropertyItem( lang.get( "plsSelect" ), 0 ) );
|
||||
for (int i = 30; i < 131; i++) {
|
||||
propertys.Add( new PropertyItem( i + " kg", i ) );
|
||||
}
|
||||
return propertys;
|
||||
}
|
||||
/// <summary>
|
||||
/// 是否是“请选择”这个值
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
public static Boolean IsSelectTip( String name ) {
|
||||
if (name == null) return false;
|
||||
return name.Equals( lang.get( "plsSelect" ) );
|
||||
}
|
||||
|
||||
private static String[] getOneDayTime() {
|
||||
|
||||
String[] result = new string[48];
|
||||
|
||||
result[0] = "0:00";
|
||||
result[1] = "0:30";
|
||||
|
||||
result[2] = "1:00";
|
||||
result[3] = "1:30";
|
||||
|
||||
result[4] = "2:00";
|
||||
result[5] = "2:30";
|
||||
|
||||
result[6] = "3:00";
|
||||
result[7] = "3:30";
|
||||
|
||||
result[8] = "4:00";
|
||||
result[9] = "4:30";
|
||||
|
||||
result[10] = "5:00";
|
||||
result[11] = "5:30";
|
||||
|
||||
result[12] = "6:00";
|
||||
result[13] = "6:30";
|
||||
|
||||
result[14] = "7:00";
|
||||
result[15] = "7:30";
|
||||
|
||||
result[16] = "8:00";
|
||||
result[17] = "8:30";
|
||||
|
||||
result[18] = "9:00";
|
||||
result[19] = "9:30";
|
||||
|
||||
result[20] = "10:00";
|
||||
result[21] = "10:30";
|
||||
|
||||
result[22] = "11:00";
|
||||
result[23] = "11:30";
|
||||
|
||||
result[24] = "12:00";
|
||||
result[25] = "12:30";
|
||||
|
||||
result[26] = "13:00";
|
||||
result[27] = "13:30";
|
||||
|
||||
result[28] = "14:00";
|
||||
result[29] = "14:30";
|
||||
|
||||
result[30] = "15:00";
|
||||
result[31] = "15:30";
|
||||
|
||||
result[32] = "16:00";
|
||||
result[33] = "16:30";
|
||||
|
||||
result[34] = "17:00";
|
||||
result[35] = "17:30";
|
||||
|
||||
result[36] = "18:00";
|
||||
result[37] = "18:30";
|
||||
|
||||
result[38] = "19:00";
|
||||
result[39] = "19:30";
|
||||
|
||||
result[40] = "20:00";
|
||||
result[41] = "20:30";
|
||||
|
||||
result[42] = "21:00";
|
||||
result[43] = "21:30";
|
||||
|
||||
result[44] = "22:00";
|
||||
result[45] = "22:30";
|
||||
|
||||
result[46] = "23:00";
|
||||
result[47] = "23:30";
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取数值列表,用于下拉选项。自动在第一项前面增加“请选择”项,其值为0
|
||||
/// </summary>
|
||||
/// <param name="intFrom">起始值</param>
|
||||
/// <param name="intTo">终止值</param>
|
||||
/// <returns>数值列表</returns>
|
||||
public static PropertyCollection GetInts( int intFrom, int intTo ) {
|
||||
|
||||
PropertyCollection propertys = new PropertyCollection();
|
||||
propertys.Add( new PropertyItem( lang.get( "plsSelect" ), 0 ) );
|
||||
|
||||
for (int i = intFrom; i <= intTo; i++) {
|
||||
propertys.Add( new PropertyItem( i.ToString(), i ) );
|
||||
}
|
||||
|
||||
return propertys;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Zhaizj.Framework.Common.Resource {
|
||||
|
||||
/// <summary>
|
||||
/// 属性数据列表,常用于下拉列表中
|
||||
/// </summary>
|
||||
public class PropertyCollection : CollectionBase {
|
||||
public int Add( PropertyItem item ) {
|
||||
return List.Add( item );
|
||||
}
|
||||
|
||||
public Boolean Contains( PropertyItem item ) {
|
||||
return List.Contains( item );
|
||||
}
|
||||
|
||||
public PropertyItem FindByValue( int val ) {
|
||||
foreach (PropertyItem item in List) {
|
||||
if (item.Value == val) {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public String GetName( int val ) {
|
||||
PropertyItem item = FindByValue( val );
|
||||
if (item == null) return "";
|
||||
if (AppResource.IsSelectTip( item.Name )) return "";
|
||||
return item.Name;
|
||||
}
|
||||
|
||||
public int IndexOf( PropertyItem item ) {
|
||||
return List.IndexOf( item );
|
||||
}
|
||||
|
||||
public void Insert( int index, PropertyItem item ) {
|
||||
List.Insert( index, item );
|
||||
}
|
||||
|
||||
public void Remove( PropertyItem item ) {
|
||||
List.Remove( item );
|
||||
}
|
||||
|
||||
public PropertyItem this[int index] {
|
||||
get { return (PropertyItem)List[index]; }
|
||||
set { List[index] = value; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
using System;
|
||||
|
||||
namespace Zhaizj.Framework.Common.Resource {
|
||||
|
||||
/// <summary>
|
||||
/// 属性数据项,常用于下拉列表中
|
||||
/// </summary>
|
||||
public class PropertyItem {
|
||||
|
||||
private String _name;
|
||||
private int _value;
|
||||
|
||||
public PropertyItem() {
|
||||
}
|
||||
|
||||
public PropertyItem( String name, int val ) {
|
||||
_name = name;
|
||||
_value = val;
|
||||
}
|
||||
|
||||
public String Name {
|
||||
get { return _name; }
|
||||
set { _name = value; }
|
||||
}
|
||||
|
||||
public int Value {
|
||||
get { return _value; }
|
||||
set { _value = value; }
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Text;
|
||||
|
||||
using Zhaizj.Framework.ORM;
|
||||
|
||||
namespace Zhaizj.Framework.Common.Security {
|
||||
|
||||
/// <summary>
|
||||
/// 角色代理对象,对象临时转换使用
|
||||
/// </summary>
|
||||
public class RoleProxy : IRole {
|
||||
|
||||
public int Id { get; set; }
|
||||
public String Name { get; set; }
|
||||
public IRole Role { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
using System;
|
||||
|
||||
namespace Zhaizj.Framework.Common.Security {
|
||||
|
||||
/// <summary>
|
||||
/// 网站用户的角色分组枚举(管理组和普通组)
|
||||
/// </summary>
|
||||
public class RoleGroup {
|
||||
|
||||
public static readonly int Admin = 1;
|
||||
public static readonly int Normal = 2;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
|
||||
namespace Zhaizj.Framework.Common.Security {
|
||||
|
||||
/// <summary>
|
||||
/// action ½Ó¿Ú
|
||||
/// </summary>
|
||||
public interface IAction {
|
||||
|
||||
int Id { get; set; }
|
||||
String Name { get; set; }
|
||||
String ActionUrl { get; set; }
|
||||
String Tip { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
|
||||
namespace Zhaizj.Framework.Common.Security {
|
||||
|
||||
/// <summary>
|
||||
/// ½ÇÉ«½Ó¿Ú
|
||||
/// </summary>
|
||||
public interface IRole {
|
||||
|
||||
int Id { get; set; }
|
||||
String Name { get; set; }
|
||||
|
||||
IRole Role { get; set; }
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
using System;
|
||||
|
||||
namespace Zhaizj.Framework.Common.Security {
|
||||
|
||||
/// <summary>
|
||||
/// 可存储权限数据的对象接口
|
||||
/// </summary>
|
||||
public interface ISecurity {
|
||||
|
||||
String Security { get; set; }
|
||||
Result update();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Text;
|
||||
|
||||
namespace Zhaizj.Framework.Common.Security {
|
||||
|
||||
/// <summary>
|
||||
/// 权限系统中的 action 接口
|
||||
/// </summary>
|
||||
public interface ISecurityAction {
|
||||
|
||||
int Id { get; set; }
|
||||
String Name { get; set; }
|
||||
String Url { get; set; }
|
||||
|
||||
IList findAll();
|
||||
ISecurityAction GetById( int id );
|
||||
void insert();
|
||||
Result update();
|
||||
void delete();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Text;
|
||||
|
||||
namespace Zhaizj.Framework.Common.Security {
|
||||
|
||||
/// <summary>
|
||||
/// ½ÇÉ«ºÏ²¢¹¤¾ß
|
||||
/// </summary>
|
||||
public class RoleMerger {
|
||||
|
||||
private IList results = new ArrayList();
|
||||
private int iCount = 1;
|
||||
|
||||
public RoleMerger() {
|
||||
}
|
||||
|
||||
public RoleMerger( IList roles ) {
|
||||
this.Add( roles );
|
||||
}
|
||||
|
||||
public RoleMerger Add( IList roles ) {
|
||||
|
||||
foreach (IRole obj in roles) {
|
||||
|
||||
RoleProxy rr = new RoleProxy();
|
||||
rr.Id = iCount;
|
||||
rr.Name = obj.Role.Name;
|
||||
rr.Role = obj.Role;
|
||||
|
||||
results.Add( rr );
|
||||
iCount++;
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public IList GetResults() {
|
||||
return results;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Text;
|
||||
using Zhaizj.Framework.ORM;
|
||||
|
||||
namespace Zhaizj.Framework.Common.Security {
|
||||
|
||||
/// <summary>
|
||||
/// 权限序列化后工具,格式:Zhaizj.Framework.Security.Domain.SiteRole:2:1,2,8,16,17/
|
||||
/// </summary>
|
||||
public class SecurityString {
|
||||
|
||||
public static char roleSeperator = '/';
|
||||
public static char itemSeperator = ':';
|
||||
public static char actionIdSeperator = ',';
|
||||
|
||||
public Type RoleType { get; set; }
|
||||
public String TypeFullName { get; set; }
|
||||
public int RoleId { get; set; }
|
||||
public int[] ActionIds { get; set; }
|
||||
|
||||
public SecurityString( String typeFullName, int roleId, IList actions ) {
|
||||
|
||||
Type roleType = Entity.GetType( typeFullName );
|
||||
if (roleType == null || !rft.IsInterface( roleType, typeof( IRole ) )) return;
|
||||
|
||||
if (roleId < 0) return;
|
||||
if (actions == null) return;
|
||||
|
||||
int[] aids = new int[actions.Count];
|
||||
for (int i = 0; i < actions.Count; i++) {
|
||||
aids[i] = ((ISecurityAction)actions[i]).Id;
|
||||
}
|
||||
|
||||
this.RoleType = roleType;
|
||||
this.TypeFullName = typeFullName;
|
||||
this.RoleId = roleId;
|
||||
this.ActionIds = aids;
|
||||
|
||||
}
|
||||
|
||||
public SecurityString( String strOne ) {
|
||||
parse( strOne );
|
||||
}
|
||||
|
||||
private void parse( String strOne ) {
|
||||
|
||||
if (strUtil.IsNullOrEmpty( strOne )) return;
|
||||
strOne = strOne.TrimEnd( roleSeperator );
|
||||
String[] arrItem = strOne.Split( itemSeperator );
|
||||
if (arrItem.Length != 3) return;
|
||||
|
||||
String typeFullName = arrItem[0].Trim();
|
||||
Type roleType = Entity.GetType( typeFullName );
|
||||
if (roleType == null || !rft.IsInterface( roleType, typeof( IRole ) )) return;
|
||||
|
||||
int roleId = cvt.ToInt( arrItem[1].Trim() );
|
||||
if (roleId < 0) return;
|
||||
|
||||
int[] Ids = cvt.ToIntArray( arrItem[2].Trim().Replace( '_', ',' ) );
|
||||
foreach (int intOne in Ids) {
|
||||
if (intOne <= 0) return;
|
||||
}
|
||||
|
||||
this.RoleType = roleType;
|
||||
this.TypeFullName = typeFullName;
|
||||
this.RoleId = roleId;
|
||||
this.ActionIds = Ids;
|
||||
}
|
||||
|
||||
public override String ToString() {
|
||||
if (strUtil.IsNullOrEmpty( this.TypeFullName )) return "";
|
||||
if (this.RoleId < 0) return "";
|
||||
if (this.ActionIds == null) return "";
|
||||
return String.Format( "{0}:{1}:{2}", this.TypeFullName, this.RoleId, cvt.ToString( ActionIds ).Replace( ',', '_' ) );
|
||||
}
|
||||
|
||||
public String GetKey() {
|
||||
return GetRoleKey( this.TypeFullName, this.RoleId );
|
||||
}
|
||||
|
||||
public static String GetRoleKey( String typeFullName, int roleId ) {
|
||||
return String.Format( "{0}_{1}", typeFullName, roleId );
|
||||
}
|
||||
|
||||
public Boolean IsError() {
|
||||
return (this.RoleType == null);
|
||||
}
|
||||
|
||||
public IList GetActions( IList actionAll ) {
|
||||
IList results = new ArrayList();
|
||||
foreach (ISecurityAction action in actionAll) {
|
||||
foreach (int actionId in ActionIds) {
|
||||
if (action.Id == actionId) {
|
||||
results.Add( action );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Configuration;
|
||||
using System.Web;
|
||||
using System.Web.Configuration;
|
||||
using Zhaizj.Framework.Utils;
|
||||
|
||||
namespace Zhaizj.Framework.Config.DotNetConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// 配置组(依赖 .NET的配置架构)
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <code>
|
||||
/// <configSections>
|
||||
/// <sectionGroup name="KEB.devfx" type="KEB.DevFx.Config.DotNetConfig.GroupHandler, KEB.DevFx.BaseFx">
|
||||
/// <section name="mail" type="KEB.DevFx.Utils.Mail.Config.SectionHandler, KEB.DevFx.BaseFx" />
|
||||
/// ......
|
||||
/// </sectionGroup>
|
||||
/// </configSections>
|
||||
///
|
||||
/// ......
|
||||
///
|
||||
/// <KEB.devfx>
|
||||
/// <mail>
|
||||
/// <smtpSetting server="" port="" userName="" password="" />
|
||||
/// </mail>
|
||||
/// </KEB.devfx>
|
||||
/// ......
|
||||
/// </code>
|
||||
/// </remarks>
|
||||
public class GroupHandler : ConfigurationSectionGroup
|
||||
{
|
||||
private static GroupHandler instance;
|
||||
private static bool isInit;
|
||||
private static bool isWebApp;
|
||||
private static Dictionary<Type, ConfigurationSection> sectionCache;
|
||||
private static readonly object lockObject = new object();
|
||||
|
||||
private static void Init(bool throwOnError) {
|
||||
if (isInit) {
|
||||
return;
|
||||
}
|
||||
Configuration config;
|
||||
if (HttpContext.Current != null) {
|
||||
isWebApp = true;
|
||||
config = WebConfigurationManager.OpenWebConfiguration(HttpContext.Current.Request.ApplicationPath);
|
||||
} else {
|
||||
isWebApp = false;
|
||||
config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
|
||||
}
|
||||
foreach (string key in config.SectionGroups.Keys) {
|
||||
ConfigurationSectionGroup csg = config.SectionGroups[key];
|
||||
if(csg == null || string.IsNullOrEmpty(csg.Type)) {
|
||||
continue;
|
||||
}
|
||||
Type csgType = TypeHelper.CreateType(csg.Type, false);
|
||||
if (csgType == typeof(GroupHandler)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
sectionCache = new Dictionary<Type, ConfigurationSection>();
|
||||
|
||||
if (instance == null) {
|
||||
isInit = true;
|
||||
if (throwOnError) {
|
||||
throw new Exception("配置组未正确配置");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (ConfigurationSection section in instance.Sections) {
|
||||
string sectionTypeName = section.SectionInformation.Type;
|
||||
string sectionName = section.SectionInformation.SectionName;
|
||||
Type sectionType = TypeHelper.CreateType(sectionTypeName, false);
|
||||
object objectSection;
|
||||
if (isWebApp) {
|
||||
objectSection = WebConfigurationManager.GetSection(sectionName);
|
||||
} else {
|
||||
objectSection = ConfigurationManager.GetSection(sectionName);
|
||||
}
|
||||
if (objectSection != null) {
|
||||
sectionCache.Add(sectionType, (ConfigurationSection)objectSection);
|
||||
}
|
||||
}
|
||||
|
||||
isInit = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 当前配置组的实例(单件)
|
||||
/// </summary>
|
||||
public static GroupHandler Instance {
|
||||
get { return instance; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取配置节(泛型)
|
||||
/// </summary>
|
||||
/// <typeparam name="T">配置节类型</typeparam>
|
||||
/// <returns>配置节</returns>
|
||||
public static T GetSection<T>() where T : ConfigurationSection {
|
||||
return GetSection<T>(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取配置节(泛型)
|
||||
/// </summary>
|
||||
/// <typeparam name="T">配置节类型</typeparam>
|
||||
/// <param name="throwOnError">如果配置组未配置是否抛出异常</param>
|
||||
/// <returns>配置节</returns>
|
||||
public static T GetSection<T>(bool throwOnError) where T : ConfigurationSection {
|
||||
if (!isInit) {
|
||||
lock (lockObject) {
|
||||
if (!isInit) {
|
||||
Init(throwOnError);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Type type = typeof(T);
|
||||
ConfigurationSection sectionObject;
|
||||
sectionCache.TryGetValue(type, out sectionObject);
|
||||
return sectionObject as T;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 构造方法
|
||||
/// </summary>
|
||||
protected GroupHandler() {
|
||||
instance = this;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
using System;
|
||||
|
||||
namespace Zhaizj.Framework.Config {
|
||||
|
||||
/// <summary>
|
||||
/// Ⱥ×éÅäÖÃ
|
||||
/// </summary>
|
||||
public class GroupSetting {
|
||||
|
||||
public int LogoHeight {
|
||||
get { return 120; }
|
||||
}
|
||||
|
||||
public int LogoWidth {
|
||||
get { return 120; }
|
||||
}
|
||||
|
||||
public int TemplateId {
|
||||
get { return 1; }
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
using System.Configuration;
|
||||
using System.Reflection;
|
||||
using System.Xml;
|
||||
using Zhaizj.Framework.Data;
|
||||
|
||||
namespace Zhaizj.Framework.Config.DotNetConfig
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// 配置节基础处理类,继承自 <see cref="ConfigurationSection"/>
|
||||
/// </summary>
|
||||
/// <typeparam name="T">派生类</typeparam>
|
||||
/// <remarks>
|
||||
/// 注意与 <see cref="BaseConfigurationElement"/> 的区别
|
||||
/// </remarks>
|
||||
public abstract class SectionBaseHandler<T> : ConfigurationSection where T : SectionBaseHandler<T>
|
||||
{
|
||||
/// <summary>
|
||||
/// 字段绑定预置值
|
||||
/// </summary>
|
||||
public const BindingFlags FieldBindingFlags = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
|
||||
/// <summary>
|
||||
/// 获取当前配置节实例
|
||||
/// </summary>
|
||||
public static T Current {
|
||||
get { return GroupHandler.GetSection<T>(false); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取一个值,该值指示反序列化过程中是否遇到未知属性
|
||||
/// </summary>
|
||||
/// <param name="name">无法识别的属性的名称</param>
|
||||
/// <param name="value">无法识别的属性的值</param>
|
||||
/// <returns>如果反序列化过程中遇到未知属性,则为<c>true</c></returns>
|
||||
protected override bool OnDeserializeUnrecognizedAttribute(string name, string value) {
|
||||
return this.OnDeserializeUnrecognizedFlag;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取一个值,该值指示反序列化过程中是否遇到未知元素
|
||||
/// </summary>
|
||||
/// <param name="elementName">未知的子元素的名称</param>
|
||||
/// <param name="reader">用于反序列化的 <seealso cref="XmlReader"/> 对象</param>
|
||||
/// <returns>如果反序列化过程中遇到未知元素,则为 true</returns>
|
||||
protected override bool OnDeserializeUnrecognizedElement(string elementName, XmlReader reader) {
|
||||
return this.OnDeserializeUnrecognizedFlag;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否遇到未知的属性或元素
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>派生类如果要允许未定义的属性,则必须重写本属性</para>
|
||||
/// </remarks>
|
||||
protected virtual bool OnDeserializeUnrecognizedFlag {
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 本配置节对应的Xml
|
||||
/// </summary>
|
||||
public virtual string OuterXml {
|
||||
get { return this.outerXml; }
|
||||
}
|
||||
|
||||
private string outerXml;
|
||||
|
||||
/// <summary>
|
||||
/// 读取配置文件中的 XML
|
||||
/// </summary>
|
||||
/// <param name="reader">在配置文件中进行读取操作的 <seealso cref="XmlReader"/></param>
|
||||
/// <param name="serializeCollectionKey">为 <c>true</c>,则只序列化集合的键属性;否则为 <c>false</c></param>
|
||||
protected override void DeserializeElement(XmlReader reader, bool serializeCollectionKey) {
|
||||
FieldInfo field = reader.GetType().GetField("_rawXml", FieldBindingFlags);
|
||||
this.outerXml = (string)field.GetValue(reader);
|
||||
base.DeserializeElement(reader, serializeCollectionKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
using System;
|
||||
|
||||
namespace Zhaizj.Framework.Config {
|
||||
|
||||
/// <summary>
|
||||
/// 配置项
|
||||
/// </summary>
|
||||
public interface ISetting {
|
||||
|
||||
int Id { get; set; }
|
||||
|
||||
String DataType { get; set; }
|
||||
|
||||
String Name { get; set; }
|
||||
String Description { get; set; }
|
||||
|
||||
// 格式json
|
||||
String Options { get; set; }
|
||||
|
||||
String SettingValue { get; set; }
|
||||
|
||||
|
||||
String ValueString { get; }
|
||||
int ValueInt { get; }
|
||||
Boolean ValueBool { get; }
|
||||
DateTime ValueTime { get; }
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
|
||||
namespace Zhaizj.Framework.Config {
|
||||
|
||||
/// <summary>
|
||||
/// 配置值的接口
|
||||
/// </summary>
|
||||
public interface ISettingValue {
|
||||
|
||||
int Id { get; set; }
|
||||
String DataType { get; set; }
|
||||
|
||||
String SettingValue { get; set; }
|
||||
void Update( String propertyName );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using Zhaizj.Framework.Common.Resource;
|
||||
using Zhaizj.Framework.Serialization;
|
||||
|
||||
using Zhaizj.Framework.Web;
|
||||
using Zhaizj.Framework.Web.Context;
|
||||
using Zhaizj.Framework.Web.Mvc;
|
||||
|
||||
namespace Zhaizj.Framework.Config {
|
||||
|
||||
/// <summary>
|
||||
/// ÅäÖÃ±íµ¥¹¤¾ß
|
||||
/// </summary>
|
||||
public class SettingFormTool {
|
||||
|
||||
public static void BindTemplate( Template template, IList list, String categoryName, String actionUrl ) {
|
||||
template.Set( "settingCategory.Name", categoryName );
|
||||
template.Set( "ActionUrl", actionUrl );
|
||||
IBlock block = template.GetBlock( "list" );
|
||||
foreach (ISetting setting in list) {
|
||||
block.Set( "setting.Id", setting.Id );
|
||||
block.Set( "setting.Title", setting.Name );
|
||||
SetInput( block, setting );
|
||||
SetNote( block, setting );
|
||||
block.Next();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static void SetInput( IBlock block, ISetting setting ) {
|
||||
|
||||
String lbl = "setting.inputControl";
|
||||
String inputName = GetInputName( setting.Id );
|
||||
String settingValue = setting.SettingValue;
|
||||
int width = 500;
|
||||
if (setting.DataType == SettingType.Int.ToString()) {
|
||||
block.Set( lbl, Html.TextInput( inputName, settingValue, "width:40px;" ) );
|
||||
}
|
||||
else if (setting.DataType == SettingType.Bool.ToString()) {
|
||||
block.Set( lbl, Html.CheckBox( inputName, "", "1", Convert.ToBoolean( setting.SettingValue ) ) );
|
||||
}
|
||||
else if (setting.DataType == SettingType.Droplist.ToString()) {
|
||||
block.Set( lbl, Html.DropList( getDropOptions(setting.Options), inputName, "Name", "Value", setting.ValueInt ) );
|
||||
}
|
||||
else if (setting.DataType == SettingType.ShortText.ToString()) {
|
||||
block.Set( lbl, Html.TextInput( inputName, settingValue, "width:" + width + "px;" ) );
|
||||
}
|
||||
else if (setting.DataType == SettingType.BigText.ToString()) {
|
||||
block.Set( lbl, Html.TextArea( inputName, settingValue, "width:" + width + "px;height:300px;" ) );
|
||||
}
|
||||
else {
|
||||
block.Set( lbl, Html.TextArea( inputName, settingValue, "width:" + width + "px;height:50px;" ) );
|
||||
}
|
||||
}
|
||||
|
||||
private static PropertyCollection getDropOptions( String Options ) {
|
||||
|
||||
PropertyCollection result = new PropertyCollection();
|
||||
if (strUtil.IsNullOrEmpty( Options )) return result;
|
||||
|
||||
Dictionary<String, object> dic = JsonParser.Parse( Options ) as Dictionary<String, object>;
|
||||
foreach (KeyValuePair<String, object> pair in dic) {
|
||||
result.Add( new PropertyItem( pair.Key, cvt.ToInt( pair.Value ) ) );
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void SetNote( IBlock block, ISetting setting ) {
|
||||
if (strUtil.HasText( setting.Description )) {
|
||||
if ((setting.DataType == SettingType.Int.ToString()) || (setting.DataType == SettingType.Bool.ToString())) {
|
||||
block.Set( "setting.Note", "<span class=\"note\">(" + setting.Description + ")</span>" );
|
||||
}
|
||||
else {
|
||||
block.Set( "setting.Note", "<div class=\"note\">(" + setting.Description + ")</div>" );
|
||||
}
|
||||
}
|
||||
else {
|
||||
block.Set( "setting.Note", "" );
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
|
||||
public static void UpdateSettings( IList list, MvcContext ctx ) {
|
||||
for (int i = 0; i < list.Count; i++) {
|
||||
ISettingValue s = list[i] as ISettingValue;
|
||||
String target = ctx.Post( GetInputName( s.Id ) );
|
||||
if (strUtil.HasText( target )) {
|
||||
if (s.DataType == SettingType.Bool.ToString()) {
|
||||
updateSetting( s, cvt.ToBool( target ).ToString() );
|
||||
}
|
||||
else if (!(s.DataType == SettingType.Int.ToString()) || cvt.IsInt( target )) {
|
||||
updateSetting( s, target );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void updateSetting( ISettingValue s, String val ) {
|
||||
if ((val != null) && (s.SettingValue.ToLower() != val.ToLower())) {
|
||||
s.SettingValue = val;
|
||||
s.Update( "SettingValue" );
|
||||
}
|
||||
}
|
||||
|
||||
private static String GetInputName( int settingId ) {
|
||||
return ("SettingValue" + settingId);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
using System;
|
||||
|
||||
namespace Zhaizj.Framework.Config {
|
||||
|
||||
/// <summary>
|
||||
/// 配置项的数据类型
|
||||
/// </summary>
|
||||
public enum SettingType {
|
||||
|
||||
Int,
|
||||
Bool,
|
||||
ShortText,
|
||||
LongText,
|
||||
BigText,
|
||||
Droplist
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,712 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Text;
|
||||
using System.Collections.Generic;
|
||||
using Zhaizj.Framework.Web.Handler;
|
||||
using Zhaizj.Framework.Web.Mvc;
|
||||
|
||||
namespace Zhaizj.Framework.Config {
|
||||
|
||||
/// <summary>
|
||||
/// 注册类型
|
||||
/// </summary>
|
||||
public class RegisterType {
|
||||
|
||||
/// <summary>
|
||||
/// 开放注册
|
||||
/// </summary>
|
||||
public static readonly int Open = 0;
|
||||
|
||||
/// <summary>
|
||||
/// 关闭注册
|
||||
/// </summary>
|
||||
public static readonly int Close = 1;
|
||||
|
||||
/// <summary>
|
||||
/// 关闭注册,但受邀请的除外
|
||||
/// </summary>
|
||||
public static readonly int CloseUnlessInvite = 2;
|
||||
}
|
||||
|
||||
public class LoginType {
|
||||
|
||||
/// <summary>
|
||||
/// 注册之后自动登录
|
||||
/// </summary>
|
||||
public static readonly int Open = 0;
|
||||
|
||||
/// <summary>
|
||||
/// 注册之后并不自动登录;必须激活才能登录
|
||||
/// </summary>
|
||||
public static readonly int ActivationEmail = 1;
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// (网站页面顶部的)用户导航栏的显示状态
|
||||
/// </summary>
|
||||
public class TopNavDisplay {
|
||||
|
||||
/// <summary>
|
||||
/// 显示
|
||||
/// </summary>
|
||||
public static readonly int Show = 0;
|
||||
|
||||
/// <summary>
|
||||
/// 隐藏
|
||||
/// </summary>
|
||||
public static readonly int Hide = 1;
|
||||
|
||||
/// <summary>
|
||||
/// 在关闭注册之后隐藏
|
||||
/// </summary>
|
||||
public static readonly int NoRegHide = 2;
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 显示名称:Name 用户名,RealName 真实姓名,默认为RealName
|
||||
/// </summary>
|
||||
public class UserDisplayNameType
|
||||
{
|
||||
public static readonly int RealName = 1;
|
||||
public static readonly int Name = 2;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 网站配置
|
||||
/// </summary>
|
||||
public class SiteSetting {
|
||||
|
||||
//-------------------------------base---------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// 网站名称
|
||||
/// </summary>
|
||||
public String SiteName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 网站的网址
|
||||
/// </summary>
|
||||
public String SiteUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// logo的图片网址
|
||||
/// </summary>
|
||||
public String SiteLogo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 站长名字
|
||||
/// </summary>
|
||||
public String Webmaster { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 网站的email
|
||||
/// </summary>
|
||||
public String Email { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 网页默认关键词
|
||||
/// </summary>
|
||||
public String Keywords { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 网页默认的描述
|
||||
/// </summary>
|
||||
public String Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 网页默认的标题
|
||||
/// </summary>
|
||||
public String PageDefaultTitle { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 网站是否需要登录才能访问,默认不需要登录
|
||||
/// </summary>
|
||||
public Boolean NeedLogin { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 用户注册之后必须经过人工审核
|
||||
/// </summary>
|
||||
public Boolean UserNeedApprove { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 对尚未激活的用户,是否提醒他激活
|
||||
/// </summary>
|
||||
public Boolean AlertActivation { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 用户自己重发激活邮件的间隔
|
||||
/// </summary>
|
||||
public int UserSendConfirmEmailInterval { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 对尚未上传头像的用户,是否提醒他上传头像
|
||||
/// </summary>
|
||||
public Boolean AlertUserPic { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 注册的三种类型 (1)开放注册 (2)关闭注册 (3)只有受邀请用户才可以注册
|
||||
/// </summary>
|
||||
public int RegisterType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 登录限制(1)注册之后自动登录 (2)必须激活才能登录)
|
||||
/// </summary>
|
||||
public int LoginType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 顶部用户栏状态(1)显示 (2)隐藏 (3)在关闭注册之后隐藏
|
||||
/// </summary>
|
||||
public int TopNavDisplay { get; set; }
|
||||
|
||||
private String _initApp;
|
||||
|
||||
/// <summary>
|
||||
/// 用户注册之后默认安装的app。
|
||||
/// </summary>
|
||||
public String UserInitApp {
|
||||
get {
|
||||
//if (strUtil.IsNullOrEmpty( _initApp )) return "home, blog, photo";
|
||||
if (strUtil.IsNullOrEmpty( _initApp )) return "";
|
||||
return _initApp;
|
||||
}
|
||||
set { _initApp = value; }
|
||||
}
|
||||
|
||||
private int _ValidationType;
|
||||
|
||||
/// <summary>
|
||||
/// 验证码类型
|
||||
/// </summary>
|
||||
public int ValidationType {
|
||||
get {
|
||||
if (_ValidationType == 0) return ValidationDefault.Type;
|
||||
return _ValidationType;
|
||||
}
|
||||
set {
|
||||
_ValidationType = value;
|
||||
}
|
||||
}
|
||||
|
||||
private int _ValidationLength;
|
||||
|
||||
/// <summary>
|
||||
/// 英文或数字的验证没长度
|
||||
/// </summary>
|
||||
public int ValidationLength {
|
||||
get {
|
||||
if (_ValidationLength == 0) return ValidationDefault.Length;
|
||||
return _ValidationLength;
|
||||
}
|
||||
set {
|
||||
_ValidationLength = value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private int _ValidationChineseLength;
|
||||
|
||||
/// <summary>
|
||||
/// 中文验证码长度
|
||||
/// </summary>
|
||||
public int ValidationChineseLength {
|
||||
get {
|
||||
if (_ValidationChineseLength == 0) return ValidationDefault.ChineseLength;
|
||||
return _ValidationChineseLength;
|
||||
}
|
||||
set {
|
||||
_ValidationChineseLength = value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public Boolean IsInstall { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 网站是否关闭
|
||||
/// </summary>
|
||||
public Boolean IsClose { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 如果关闭,关闭的原因
|
||||
/// </summary>
|
||||
public String CloseReason { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否开启统计,需要结合StatsJs
|
||||
/// </summary>
|
||||
public Boolean StatsEnabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 统计js
|
||||
/// </summary>
|
||||
public String StatsJs { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 版权信息
|
||||
/// </summary>
|
||||
public String Copyright { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// logo宽度
|
||||
/// </summary>
|
||||
public int LogoWidth { get { return 250; } }
|
||||
|
||||
/// <summary>
|
||||
/// logo高度
|
||||
/// </summary>
|
||||
public int LogoHeight { get { return 80; } }
|
||||
|
||||
/// <summary>
|
||||
/// 网站当前皮肤的ID
|
||||
/// </summary>
|
||||
public int SkinId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 用户密码是否采用16位的md5加密方式(默认为否,用于兼容旧的系统)
|
||||
/// </summary>
|
||||
public Boolean Md5Is16 { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 评论内容的长度
|
||||
/// </summary>
|
||||
public int CommentLength { get { return 500; } }
|
||||
|
||||
private int _TagLength;
|
||||
|
||||
/// <summary>
|
||||
/// tag的长度
|
||||
/// </summary>
|
||||
public int TagLength {
|
||||
get {
|
||||
if (_TagLength == 0) return 20;
|
||||
return _TagLength;
|
||||
}
|
||||
set {
|
||||
_TagLength = value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 网站logo图片的完整网址
|
||||
/// </summary>
|
||||
public String SiteLogoFull {
|
||||
get { return strUtil.Join( sys.Path.Photo, this.SiteLogo ); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取统计的js内容
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public String GetStatsJs() {
|
||||
if (this.StatsEnabled == false) return "";
|
||||
return this.StatsJs;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 如果设置了logo图片,返回img;否则返回siteName
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public String GetLogoHtml() {
|
||||
|
||||
String logo;
|
||||
if (strUtil.HasText( this.SiteLogo )) {
|
||||
logo = "<img src=\"" + SiteLogoFull + "?v=" + MvcConfig.Instance.CssVersion + "\"/>";
|
||||
}
|
||||
else {
|
||||
logo = "<div class=\"nologo\">" + this.SiteName + "</div>";
|
||||
}
|
||||
|
||||
return logo;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取邮件发送服务器的域名,比如根据 abc@gmail.com,得到 gmail.com
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public String GetSmtpUserDomain() {
|
||||
return GetSmtpUserDomain( this.SmtpUser );
|
||||
}
|
||||
|
||||
public String GetSmtpUserDomain( string smtpUser ) {
|
||||
if (strUtil.IsNullOrEmpty( smtpUser )) return string.Concat( 'w', 'o', 'j', 'i', 'l', 'u', '.', 'c', 'o', 'm' );
|
||||
if (smtpUser.IndexOf( '@' ) <= 0) return string.Concat( 'w', 'o', 'j', 'i', 'l', 'u', '.', 'c', 'o', 'm' );
|
||||
String[] arr = smtpUser.Split( '@' );
|
||||
return arr[1].Trim();
|
||||
}
|
||||
|
||||
//----------------------------- user -----------------------------------
|
||||
|
||||
public Boolean ShowSexyInfoInProfile { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 注册用户名允许的长度
|
||||
/// </summary>
|
||||
public int UserNameLengthMax { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 注册用户名至少要达到的长度
|
||||
/// </summary>
|
||||
public int UserNameLengthMin { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 登录是否启用验证码
|
||||
/// </summary>
|
||||
public Boolean LoginNeedImgValidation { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 注册是否启用验证码
|
||||
/// </summary>
|
||||
public Boolean RegisterNeedImgValidateion { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 给新注册用户发送的欢迎信息的标题
|
||||
/// </summary>
|
||||
public String SystemMsgTitle { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 给新注册用户发送的欢迎信息的内容(支持html)
|
||||
/// </summary>
|
||||
public String SystemMsgContent { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 保留用户名(不可以注册的用户名)
|
||||
/// </summary>
|
||||
public String[] ReservedUserName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 保留的用户个性网址
|
||||
/// </summary>
|
||||
public String[] ReservedUserUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 保留的关键词(不可以在用户名和个性网址中使用)
|
||||
/// </summary>
|
||||
public String[] ReservedKey { get; set; }
|
||||
|
||||
public Boolean IsReservedKeyContains( String inputName ) {
|
||||
|
||||
string[] arr = this.ReservedKey;
|
||||
foreach (String key in arr) {
|
||||
if (strUtil.EqualsIgnoreCase( inputName, key ) || strUtil.EqualsIgnoreCase( inputName, key + "s" )) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 使用MS的Membership数据库验证登录,需要配合AuthenticationModule的自动注册功能一起使用,默认为否
|
||||
/// </summary>
|
||||
public Boolean ValidateUserByMembership { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 显示名称:Name 用户名,RealName 真实姓名,默认为RealName
|
||||
/// </summary>
|
||||
public int UserDisplayName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否禁止修改真实性名与空间名称,默认不禁止
|
||||
/// </summary>
|
||||
public Boolean DenyEditUserRealName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否禁止修改空间名称,默认不禁止
|
||||
/// </summary>
|
||||
public Boolean DenyEditUserTitle { get; set; }
|
||||
|
||||
//------------------------------filter----------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// 禁用的关键词
|
||||
/// </summary>
|
||||
public String[] BadWords { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 禁用词汇的替换词
|
||||
/// </summary>
|
||||
public String BadWordsReplacement { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 所有被禁的ip地址
|
||||
/// </summary>
|
||||
public String[] BannedIp { get; set; }
|
||||
|
||||
private String _bannedIpInfo;
|
||||
|
||||
/// <summary>
|
||||
/// 给被屏蔽访客的警告信息
|
||||
/// </summary>
|
||||
public String BannedIpInfo {
|
||||
get {
|
||||
if (_bannedIpInfo == null) return "对不起,你的 ip 地址已被屏蔽";
|
||||
return _bannedIpInfo;
|
||||
}
|
||||
set { _bannedIpInfo = value; }
|
||||
}
|
||||
|
||||
|
||||
//public Boolean IsWatermark { get; set; }
|
||||
|
||||
|
||||
private int _microblogContentMax;
|
||||
/// <summary>
|
||||
/// 微博内容字数最高限制
|
||||
/// </summary>
|
||||
public int MicroblogContentMax {
|
||||
get {
|
||||
if (_microblogContentMax <= 0) return 140;
|
||||
return _microblogContentMax;
|
||||
}
|
||||
set {
|
||||
_microblogContentMax = value;
|
||||
}
|
||||
}
|
||||
|
||||
private int _microblogPageSize;
|
||||
/// <summary>
|
||||
/// 微博内容字数最高限制
|
||||
/// </summary>
|
||||
public int MicroblogPageSize {
|
||||
get {
|
||||
if (_microblogPageSize <= 0) return 20;
|
||||
return _microblogPageSize;
|
||||
}
|
||||
set {
|
||||
_microblogPageSize = value;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
|
||||
public Boolean EnableEmail { get; set; } // 是否开启邮件服务,比如:邮件激活等
|
||||
public String SmtpUrl { get; set; }
|
||||
public String SmtpUser { get; set; }
|
||||
public String SmtpPwd { get; set; }
|
||||
public Boolean SmtpEnableSsl { get; set; }
|
||||
|
||||
public Boolean CloseComment { get; set; }
|
||||
|
||||
//-------------------------------other---------------------------------
|
||||
|
||||
public int MaxOnline { get; set; }
|
||||
public DateTime MaxOnlineTime { get; set; }
|
||||
public int UserTemplateId { get; set; }
|
||||
|
||||
public int NoRefreshSecond { get; set; }
|
||||
|
||||
public int FeedKeepDay { get; set; }
|
||||
public DateTime LastFeedClearTime { get; set; }
|
||||
|
||||
public String[] Spider { get; set; }
|
||||
|
||||
private static string getArrayString( String[] arr ) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < arr.Length; i++) {
|
||||
sb.Append( arr[i] );
|
||||
if (i < arr.Length - 1) sb.Append( "/" );
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
|
||||
public int PhotoThumbHeight { get; set; }
|
||||
public int PhotoThumbWidth { get; set; }
|
||||
|
||||
public int PhotoThumbHeightMedium { get; set; }
|
||||
public int PhotoThumbWidthMedium { get; set; }
|
||||
|
||||
public int PhotoThumbHeightBig { get; set; }
|
||||
public int PhotoThumbWidthBig { get; set; }
|
||||
|
||||
|
||||
public int AvatarThumbHeight { get; set; }
|
||||
public int AvatarThumbWidth { get; set; }
|
||||
|
||||
public int AvatarThumbHeightMedium { get; set; }
|
||||
public int AvatarThumbWidthMedium { get; set; }
|
||||
|
||||
public int AvatarThumbHeightBig { get; set; }
|
||||
public int AvatarThumbWidthBig { get; set; }
|
||||
|
||||
public Boolean IsSaveAvatarMedium { get; set; }
|
||||
public Boolean IsSaveAvatarBig { get; set; }
|
||||
|
||||
public String[] UploadFileTypes { get; set; }
|
||||
public String[] UploadPicTypes { get; set; }
|
||||
|
||||
private int _uploadPicMaxMB;
|
||||
private int _uploadFileMaxMB;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 图片最大上传的大小,单位MB
|
||||
/// </summary>
|
||||
public int UploadPicMaxMB {
|
||||
get {
|
||||
if (_uploadPicMaxMB == 0) return 5;
|
||||
return _uploadPicMaxMB;
|
||||
}
|
||||
set { _uploadPicMaxMB = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 图片最大上传的大小,单位MB
|
||||
/// </summary>
|
||||
public int UploadFileMaxMB {
|
||||
get {
|
||||
if (_uploadFileMaxMB == 0) return 20;
|
||||
return _uploadFileMaxMB;
|
||||
}
|
||||
set { _uploadFileMaxMB = value; }
|
||||
|
||||
}
|
||||
|
||||
|
||||
// 扩展的值
|
||||
//-------------------------------------------------------------------------------------
|
||||
|
||||
public int GetValueInt( String key ) {
|
||||
return cvt.ToInt( GetValue( key ) );
|
||||
}
|
||||
|
||||
public Boolean GetValueBool( String key ) {
|
||||
return cvt.ToBool( GetValue( key ) );
|
||||
}
|
||||
|
||||
public decimal GetValueDecimal( String key ) {
|
||||
return cvt.ToDecimal( GetValue( key ) );
|
||||
}
|
||||
|
||||
public DateTime GetValueTime( String key ) {
|
||||
return cvt.ToTime( GetValue( key ) );
|
||||
}
|
||||
|
||||
public String GetValue( String key ) {
|
||||
if (strUtil.IsNullOrEmpty( key )) return null;
|
||||
if (_valueAll == null) return null;
|
||||
if (_valueAll.ContainsKey( key ) == false) return null;
|
||||
return _valueAll[key];
|
||||
}
|
||||
|
||||
//-------------------------
|
||||
|
||||
public String[] GetArrayValue( String key ) {
|
||||
return getArrayValue( _valueAll, key );
|
||||
}
|
||||
|
||||
internal String[] getArrayValue( Dictionary<String, String> dic, String key ) {
|
||||
|
||||
if (dic == null) return new String[] { };
|
||||
|
||||
if (dic.ContainsKey( key ) && strUtil.HasText( dic[key] )) {
|
||||
return GetArrayValueByString( dic[key] );
|
||||
}
|
||||
|
||||
return new String[] { };
|
||||
}
|
||||
|
||||
public static String[] GetArrayValueByString( String valOne ) {
|
||||
|
||||
if (strUtil.IsNullOrEmpty( valOne )) return new String[] { };
|
||||
|
||||
String[] arrValue = valOne.Split( new char[] { ',', '/', '|', ',', '、' } );
|
||||
|
||||
// 剔除掉无效的字符串
|
||||
ArrayList results = new ArrayList();
|
||||
foreach (String val in arrValue) {
|
||||
if (strUtil.HasText( val )) results.Add( val.Trim() );
|
||||
}
|
||||
|
||||
return (String[])results.ToArray( typeof( String ) );
|
||||
}
|
||||
|
||||
private Dictionary<String, String> _valueAll;
|
||||
|
||||
internal void setValueAll( Dictionary<String, String> valueAll ) {
|
||||
_valueAll = valueAll;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// 将更新保存到磁盘
|
||||
/// </summary>
|
||||
/// <param name="item"></param>
|
||||
/// <param name="val"></param>
|
||||
public void Update( String item, Object val ) {
|
||||
|
||||
String itemValue = "";
|
||||
if (val != null) itemValue = val.ToString();
|
||||
|
||||
itemValue = strUtil.Text2Html( itemValue );
|
||||
|
||||
saveConfig( item, itemValue );
|
||||
}
|
||||
|
||||
public void UpdateHtml( String item, Object val ) {
|
||||
|
||||
String itemValue = "";
|
||||
if (val != null) itemValue = val.ToString();
|
||||
itemValue = itemValue.Replace( "\n", "" ).Replace( "\r", "" );
|
||||
|
||||
saveConfig( item, itemValue );
|
||||
}
|
||||
|
||||
private void saveConfig( String item, String itemValue ) {
|
||||
String[] configString = file.ReadAllLines( config.siteconfigAbsPath );
|
||||
List<String> results = new List<string>();
|
||||
|
||||
checkSingleLine( item, itemValue, configString, results );
|
||||
StringBuilder sb = new StringBuilder();
|
||||
foreach (String line in results) {
|
||||
sb.Append( line );
|
||||
sb.Append( Environment.NewLine );
|
||||
}
|
||||
lock (objLock) {
|
||||
file.Write( config.siteconfigAbsPath, sb.ToString() );
|
||||
}
|
||||
}
|
||||
|
||||
private void checkSingleLine( String item, String itemValue, String[] configString, List<String> results ) {
|
||||
Boolean hasItem = false;
|
||||
foreach (String line in configString) {
|
||||
|
||||
if (startsWith( line, item )) {
|
||||
hasItem = true;
|
||||
results.Add( item + " : " + itemValue );
|
||||
_valueAll[item] = itemValue;
|
||||
}
|
||||
else {
|
||||
results.Add( line );
|
||||
}
|
||||
}
|
||||
if (hasItem == false) {
|
||||
results.Add( item + " : " + itemValue );
|
||||
_valueAll[item] = itemValue;
|
||||
}
|
||||
}
|
||||
|
||||
private static Boolean startsWith( String line, String item ) {
|
||||
|
||||
if (line.StartsWith( item )) {
|
||||
String noPrefixLine = strUtil.TrimStart( line, item ).Trim();
|
||||
if (noPrefixLine.StartsWith( ":" )) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static Object objLock = new object();
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,276 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using Zhaizj.Framework.Data;
|
||||
|
||||
namespace Zhaizj.Framework.Config
|
||||
{
|
||||
/// <summary>
|
||||
/// 关于类型、实例的一些实用方法
|
||||
/// </summary>
|
||||
public static class TypeHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// 字段绑定预置值
|
||||
/// </summary>
|
||||
public const BindingFlags FieldBindingFlags = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
|
||||
/// <summary>
|
||||
/// 从类型名称中创建类型
|
||||
/// </summary>
|
||||
/// <param name="typeName">类型名</param>
|
||||
/// <param name="throwOnError">失败时是否抛出异常</param>
|
||||
/// <returns>Type</returns>
|
||||
public static Type CreateType(string typeName, bool throwOnError) {
|
||||
try
|
||||
{
|
||||
return Type.GetType(typeName, throwOnError, false);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 在当前应用程序域中查找指定的类型
|
||||
/// </summary>
|
||||
/// <param name="assemblyFile">动态库文件的绝对路径</param>
|
||||
/// <param name="typeName">类型全名(包括命名空间)</param>
|
||||
/// <param name="throwOnError">失败时是否抛出异常</param>
|
||||
/// <returns>找到则返回指定的类型,否则返回空</returns>
|
||||
public static Type GetType(string assemblyFile, string typeName, bool throwOnError)
|
||||
{
|
||||
if (string.IsNullOrEmpty(assemblyFile))
|
||||
{
|
||||
throw new ArgumentNullException("assemblyFile");
|
||||
}
|
||||
Assembly assembly = GetAssembly(assemblyFile);
|
||||
Type type = assembly.GetType(typeName);
|
||||
|
||||
return type;
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据文件名装入程序集合
|
||||
/// </summary>
|
||||
/// <param name="path">绝对路径</param>
|
||||
/// <returns></returns>
|
||||
public static Assembly GetAssembly(string path)
|
||||
{
|
||||
if (!File.Exists(path))
|
||||
{
|
||||
throw new InvalidOperationException(path + "文件不存在或拒绝访问!");
|
||||
}
|
||||
Assembly assembly = Assembly.LoadFrom(path);
|
||||
if (assembly == null)
|
||||
throw new InvalidOperationException("无法正确载入程序集合!请确认文件格式正确。");
|
||||
return assembly;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从类型中创建此类型的实例
|
||||
/// </summary>
|
||||
/// <param name="type">类型</param>
|
||||
/// <param name="expectedType">期望的类型</param>
|
||||
/// <param name="throwOnError">失败时是否抛出异常</param>
|
||||
/// <param name="parameterTypes">创建实例所需参数的类型列表</param>
|
||||
/// <param name="parameterValues">创建实例所需的参数值列表</param>
|
||||
/// <returns>类型实例</returns>
|
||||
public static object CreateObject(Type type, Type expectedType, bool throwOnError, Type[] parameterTypes, object[] parameterValues) {
|
||||
if (expectedType != null && !expectedType.IsAssignableFrom(type)) {
|
||||
if (throwOnError) {
|
||||
throw new Exception(string.Format("将要创建的类型:{0},不是期望的类型:{1}", type.FullName, expectedType.FullName));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
if (parameterTypes != null && parameterValues != null && parameterTypes.Length != parameterValues.Length) {
|
||||
if (throwOnError) {
|
||||
throw new Exception("构造函数参数类型数量和参数数量不一致");
|
||||
}
|
||||
}
|
||||
object createdObject = null;
|
||||
ConstructorInfo constructor = type.GetConstructor(parameterTypes);
|
||||
if (constructor == null) {
|
||||
try {
|
||||
createdObject = Activator.CreateInstance(type, BindingFlags.CreateInstance | (BindingFlags.NonPublic | (BindingFlags.Public | BindingFlags.Instance)), null, parameterValues, null);
|
||||
} catch (Exception e) {
|
||||
if (throwOnError) {
|
||||
throw new Exception("即将创建的类型不支持指定的构造函数:" + e.Message, e);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
createdObject = constructor.Invoke(parameterValues);
|
||||
} catch (Exception e) {
|
||||
throw new Exception("对象创建失败:" + e.Message, e);
|
||||
}
|
||||
}
|
||||
return createdObject;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从类型中创建此类型的实例(本方法不支持参数可为Null的构造函数)
|
||||
/// </summary>
|
||||
/// <param name="type">类型</param>
|
||||
/// <param name="expectedType">期望的类型</param>
|
||||
/// <param name="throwOnError">失败时是否抛出异常</param>
|
||||
/// <param name="parameters">创建实例所需的参数值列表</param>
|
||||
/// <returns>类型实例</returns>
|
||||
public static object CreateObject(Type type, Type expectedType, bool throwOnError, params object[] parameters) {
|
||||
int paramNum = 0;
|
||||
if (parameters != null) {
|
||||
paramNum = parameters.Length;
|
||||
}
|
||||
Type[] paramTypes = new Type[paramNum];
|
||||
object[] paramValues = new object[paramNum];
|
||||
for (int i = 0; i < paramNum; i++) {
|
||||
if (parameters[i] == null) {
|
||||
if (throwOnError) {
|
||||
throw new Exception("不支持参数可为Null的构造函数,请使用本方法的另外重载版本");
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
paramTypes[i] = parameters[i].GetType();
|
||||
paramValues[i] = parameters[i];
|
||||
}
|
||||
return CreateObject(type, expectedType, throwOnError, paramTypes, paramValues);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从类型名中创建此类型的实例
|
||||
/// </summary>
|
||||
/// <param name="typeName">类型名</param>
|
||||
/// <param name="expectedType">期望的类型</param>
|
||||
/// <param name="throwOnError">失败时是否抛出异常</param>
|
||||
/// <param name="parameters">创建实例所需的参数值列表</param>
|
||||
/// <returns>类型实例</returns>
|
||||
public static object CreateObject(string typeName, Type expectedType, bool throwOnError, params object[] parameters) {
|
||||
Type type = CreateType(typeName, throwOnError);
|
||||
return CreateObject(type, expectedType, throwOnError, parameters);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从类型名中创建此类型的实例
|
||||
/// </summary>
|
||||
/// <param name="typeName">类型名</param>
|
||||
/// <param name="expectedType">期望的类型</param>
|
||||
/// <param name="throwOnError">失败时是否抛出异常</param>
|
||||
/// <param name="parameterTypes">创建实例所需参数的类型列表</param>
|
||||
/// <param name="parameterValues">创建实例所需的参数值列表</param>
|
||||
/// <returns>类型实例</returns>
|
||||
public static object CreateObject(string typeName, Type expectedType, bool throwOnError, Type[] parameterTypes, object[] parameterValues) {
|
||||
Type type = CreateType(typeName, throwOnError);
|
||||
return CreateObject(type, expectedType, throwOnError, parameterTypes, parameterValues);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 使用反射调用方法
|
||||
/// </summary>
|
||||
/// <param name="obj">类型实例</param>
|
||||
/// <param name="methodName">方法名</param>
|
||||
/// <param name="parameters">参数列表</param>
|
||||
/// <returns>方法返回值</returns>
|
||||
public static object Invoke(object obj, string methodName, params object[] parameters) {
|
||||
if (obj == null) {
|
||||
return obj;
|
||||
}
|
||||
return obj.GetType().GetMethod(methodName, FieldBindingFlags).Invoke(obj, parameters);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 在当前应用程序域中查找指定的类型
|
||||
/// </summary>
|
||||
/// <param name="typeName">类型全名(包括命名空间)</param>
|
||||
/// <returns>找到则返回指定的类型,否则返回空</returns>
|
||||
public static Type FindType(string typeName) {
|
||||
if (string.IsNullOrEmpty(typeName))
|
||||
return null;
|
||||
Type type = null;
|
||||
List<string> files = new List<string>();
|
||||
foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies()) {
|
||||
type = assembly.GetType(typeName, false);
|
||||
if (type != null) {
|
||||
break;
|
||||
} else if(!assembly.GlobalAssemblyCache) {
|
||||
files.Add(assembly.ManifestModule.ScopeName.ToLower());
|
||||
}
|
||||
}
|
||||
if(type == null) {
|
||||
string[] fileNames = Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory, "*.dll", SearchOption.TopDirectoryOnly);
|
||||
foreach (string file in fileNames) {
|
||||
try
|
||||
{
|
||||
string fileName = Path.GetFileName(file);
|
||||
if (!files.Contains(fileName.ToLower()))
|
||||
{
|
||||
//只载入在系统公用缓存中的集合
|
||||
string assemblyName = Path.GetFileNameWithoutExtension(fileName);
|
||||
string typeFullName = typeName + ", " + assemblyName;
|
||||
type = CreateType(typeFullName, false);
|
||||
if (type != null)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//从文件中载入程序集并返回类型
|
||||
type = GetType(file, typeName, false);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
}
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 从程序集中获得元属性
|
||||
/// </summary>
|
||||
/// <param name="assemblies">程序集,如果为null,则从当前应用程序域中获取所载入的所有程序集</param>
|
||||
/// <returns>找到的元属性的数组</returns>
|
||||
public static T[] GetAttributeFromAssembly<T>(Assembly[] assemblies) where T : Attribute {
|
||||
List<T> list = new List<T>();
|
||||
T[] attributes = null;
|
||||
if (assemblies == null) {
|
||||
assemblies = AppDomain.CurrentDomain.GetAssemblies();
|
||||
}
|
||||
foreach (Assembly assembly in assemblies) {
|
||||
attributes = (T[])assembly.GetCustomAttributes(typeof(T), false);
|
||||
if (attributes != null && attributes.Length > 0) {
|
||||
list.AddRange(attributes);
|
||||
}
|
||||
}
|
||||
return list.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从运行时的堆栈中获取元属性
|
||||
/// </summary>
|
||||
/// <param name="includeAll">是否包含堆栈上所有的元属性</param>
|
||||
/// <typeparam name="T">元属性类型</typeparam>
|
||||
/// <returns>找到的元属性的数组</returns>
|
||||
public static T[] GetAttributeFromRuntimeStack<T>(bool includeAll) where T : Attribute {
|
||||
var list = new List<T>();
|
||||
var t = new StackTrace();
|
||||
for (var i = 0; i < t.FrameCount; i++) {
|
||||
var f = t.GetFrame(i);
|
||||
var m = (MethodInfo)f.GetMethod();
|
||||
var a = Attribute.GetCustomAttributes(m, typeof(T)) as T[];
|
||||
if (a != null && a.Length > 0) {
|
||||
list.AddRange(a);
|
||||
if (!includeAll) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return list.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,206 @@
|
||||
using System.Collections.Generic;
|
||||
using Zhaizj.Framework.Config;
|
||||
using System;
|
||||
|
||||
namespace Zhaizj.Framework {
|
||||
|
||||
/// <summary>
|
||||
/// 网站的配置信息
|
||||
/// </summary>
|
||||
public class config {
|
||||
|
||||
|
||||
private SiteSetting _siteSetting;
|
||||
private GroupSetting _groupSetting;
|
||||
|
||||
/// <summary>
|
||||
/// 网站的配置信息
|
||||
/// </summary>
|
||||
public SiteSetting Site {
|
||||
get { return _siteSetting; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 群组的配置信息
|
||||
/// </summary>
|
||||
public GroupSetting Group {
|
||||
get { return _groupSetting; }
|
||||
}
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
private config() { loadAll(); }
|
||||
|
||||
private static volatile config _instance;
|
||||
private static Object _syncRoot = new object();
|
||||
public static config Instance {
|
||||
get {
|
||||
if (_instance == null) {
|
||||
lock (_syncRoot) {
|
||||
if (_instance == null) _instance = new config();
|
||||
}
|
||||
}
|
||||
return _instance;
|
||||
}
|
||||
}
|
||||
|
||||
private void Reload() {
|
||||
loadAll();
|
||||
}
|
||||
|
||||
|
||||
private void loadAll() {
|
||||
initSiteSettings();
|
||||
initGroupSettings();
|
||||
}
|
||||
|
||||
|
||||
private void initGroupSettings() {
|
||||
_groupSetting = new GroupSetting();
|
||||
}
|
||||
|
||||
// ------------------------- site settings -------------------------
|
||||
|
||||
private void initSiteSettings() {
|
||||
|
||||
_siteSetting = new SiteSetting();
|
||||
|
||||
Dictionary<String, String> dic = cfgHelper.Read( siteconfigAbsPath );
|
||||
if (dic.Count <= 0) return;
|
||||
|
||||
|
||||
_siteSetting.SiteName = getVal( dic, "SiteName" );
|
||||
_siteSetting.SiteUrl = getVal( dic, "SiteUrl" );
|
||||
_siteSetting.SiteLogo = getVal( dic, "SiteLogo" );
|
||||
|
||||
_siteSetting.Webmaster = getVal( dic, "Webmaster" );
|
||||
_siteSetting.Email = getVal( dic, "Email" );
|
||||
_siteSetting.Copyright = getVal( dic, "Copyright" );
|
||||
_siteSetting.Keywords = getVal( dic, "Keywords" );
|
||||
_siteSetting.Description = getVal( dic, "Description" );
|
||||
_siteSetting.PageDefaultTitle = getVal( dic, "PageDefaultTitle" );
|
||||
_siteSetting.IsClose = cvt.ToBool( getVal( dic, "IsClose" ) );
|
||||
_siteSetting.CloseReason = getVal( dic, "CloseReason" );
|
||||
_siteSetting.IsInstall = cvt.ToBool( getVal( dic, "IsInstall" ) );
|
||||
|
||||
_siteSetting.RegisterType = cvt.ToInt( getVal( dic, "RegisterType" ) );
|
||||
_siteSetting.LoginType = cvt.ToInt( getVal( dic, "LoginType" ) );
|
||||
_siteSetting.TopNavDisplay = cvt.ToInt( getVal( dic, "TopNavDisplay" ) );
|
||||
|
||||
_siteSetting.NeedLogin = cvt.ToBool( getVal( dic, "NeedLogin" ) );
|
||||
_siteSetting.UserNeedApprove = cvt.ToBool( getVal( dic, "UserNeedApprove" ) );
|
||||
|
||||
_siteSetting.AlertActivation = cvt.ToBool( getVal( dic, "AlertActivation" ) );
|
||||
_siteSetting.AlertUserPic = cvt.ToBool( getVal( dic, "AlertUserPic" ) );
|
||||
|
||||
|
||||
_siteSetting.UserSendConfirmEmailInterval = cvt.ToInt( getVal( dic, "UserSendConfirmEmailInterval" ) );
|
||||
|
||||
_siteSetting.UserInitApp = getVal( dic, "UserInitApp" );
|
||||
|
||||
//
|
||||
_siteSetting.TagLength = cvt.ToInt( getVal( dic, "TagLength" ) );
|
||||
|
||||
_siteSetting.ValidationType = cvt.ToInt( getVal( dic, "ValidationType" ) );
|
||||
_siteSetting.ValidationLength = cvt.ToInt( getVal( dic, "ValidationLength" ) );
|
||||
_siteSetting.ValidationChineseLength = cvt.ToInt( getVal( dic, "ValidationChineseLength" ) );
|
||||
|
||||
|
||||
_siteSetting.StatsEnabled = cvt.ToBool( getVal( dic, "StatsEnabled" ) );
|
||||
_siteSetting.StatsJs = getVal( dic, "StatsJs" );
|
||||
|
||||
_siteSetting.MicroblogContentMax = cvt.ToInt( getVal( dic, "MicroblogContentMax" ) );
|
||||
_siteSetting.MicroblogPageSize = cvt.ToInt( getVal( dic, "MicroblogPageSize" ) );
|
||||
|
||||
|
||||
_siteSetting.SkinId = cvt.ToInt( getVal( dic, "SkinId" ) );
|
||||
_siteSetting.Md5Is16 = cvt.ToBool( getVal( dic, "Md5Is16" ) );
|
||||
|
||||
_siteSetting.SystemMsgTitle = getVal( dic, "SystemMsgTitle" );
|
||||
_siteSetting.SystemMsgContent = getVal( dic, "SystemMsgContent" );
|
||||
_siteSetting.UserNameLengthMax = cvt.ToInt( getVal( dic, "UserNameLengthMax" ) );
|
||||
_siteSetting.UserNameLengthMin = cvt.ToInt( getVal( dic, "UserNameLengthMin" ) );
|
||||
_siteSetting.LoginNeedImgValidation = cvt.ToBool( getVal( dic, "LoginNeedImgValidation" ) );
|
||||
_siteSetting.RegisterNeedImgValidateion = cvt.ToBool( getVal( dic, "RegisterNeedImgValidateion" ) );
|
||||
_siteSetting.ShowSexyInfoInProfile = cvt.ToBool( getVal( dic, "ShowSexyInfoInProfile" ) );
|
||||
|
||||
_siteSetting.ReservedUserName = _siteSetting.getArrayValue( dic, "ReservedUserName" );
|
||||
_siteSetting.ReservedUserUrl = _siteSetting.getArrayValue( dic, "ReservedUserUrl" );
|
||||
_siteSetting.ReservedKey = _siteSetting.getArrayValue( dic, "ReservedKey" );
|
||||
|
||||
_siteSetting.PhotoThumbHeight = cvt.ToInt( getVal( dic, "PhotoThumbHeight" ) );
|
||||
_siteSetting.PhotoThumbWidth = cvt.ToInt( getVal( dic, "PhotoThumbWidth" ) );
|
||||
_siteSetting.PhotoThumbHeightMedium = cvt.ToInt( getVal( dic, "PhotoThumbHeightMedium" ) );
|
||||
_siteSetting.PhotoThumbWidthMedium = cvt.ToInt( getVal( dic, "PhotoThumbWidthMedium" ) );
|
||||
_siteSetting.PhotoThumbHeightBig = cvt.ToInt( getVal( dic, "PhotoThumbHeightBig" ) );
|
||||
_siteSetting.PhotoThumbWidthBig = cvt.ToInt( getVal( dic, "PhotoThumbWidthBig" ) );
|
||||
|
||||
_siteSetting.AvatarThumbHeight = cvt.ToInt( getVal( dic, "AvatarThumbHeight" ) );
|
||||
_siteSetting.AvatarThumbWidth = cvt.ToInt( getVal( dic, "AvatarThumbWidth" ) );
|
||||
_siteSetting.AvatarThumbHeightMedium = cvt.ToInt( getVal( dic, "AvatarThumbHeightMedium" ) );
|
||||
_siteSetting.AvatarThumbWidthMedium = cvt.ToInt( getVal( dic, "AvatarThumbWidthMedium" ) );
|
||||
_siteSetting.AvatarThumbHeightBig = cvt.ToInt( getVal( dic, "AvatarThumbHeightBig" ) );
|
||||
_siteSetting.AvatarThumbWidthBig = cvt.ToInt( getVal( dic, "AvatarThumbWidthBig" ) );
|
||||
|
||||
_siteSetting.UploadFileTypes = _siteSetting.getArrayValue( dic, "UploadFileTypes" );
|
||||
_siteSetting.UploadPicTypes = _siteSetting.getArrayValue( dic, "UploadPicTypes" );
|
||||
|
||||
_siteSetting.UploadPicMaxMB = cvt.ToInt( getVal( dic, "UploadPicMaxMB" ) );
|
||||
_siteSetting.UploadFileMaxMB = cvt.ToInt( getVal( dic, "UploadFileMaxMB" ) );
|
||||
|
||||
|
||||
_siteSetting.IsSaveAvatarMedium = cvt.ToBool( getVal( dic, "IsSaveAvatarMedium" ) );
|
||||
_siteSetting.IsSaveAvatarBig = cvt.ToBool( getVal( dic, "IsSaveAvatarBig" ) );
|
||||
|
||||
_siteSetting.BadWords = _siteSetting.getArrayValue( dic, "BadWords" );
|
||||
_siteSetting.BadWordsReplacement = getVal( dic, "BadWordsReplacement" );
|
||||
|
||||
_siteSetting.BannedIp = _siteSetting.getArrayValue( dic, "BannedIp" );
|
||||
_siteSetting.BannedIpInfo = getVal( dic, "BannedIpInfo" );
|
||||
|
||||
|
||||
_siteSetting.Spider = _siteSetting.getArrayValue( dic, "Spider" );
|
||||
if (_siteSetting.Spider.Length == 0) _siteSetting.Spider = new String[] { "spider", "robot", "Slurp", "sogou", "youdao", "google" };
|
||||
|
||||
|
||||
_siteSetting.MaxOnline = cvt.ToInt( getVal( dic, "MaxOnline" ) );
|
||||
_siteSetting.MaxOnlineTime = cvt.ToTime( getVal( dic, "MaxOnlineTime" ) );
|
||||
_siteSetting.UserTemplateId = cvt.ToInt( getVal( dic, "UserTemplateId" ) );
|
||||
|
||||
_siteSetting.FeedKeepDay = cvt.ToInt( getVal( dic, "FeedKeepDay" ) );
|
||||
_siteSetting.LastFeedClearTime = cvt.ToTime( getVal( dic, "LastFeedClearTime" ) );
|
||||
|
||||
_siteSetting.NoRefreshSecond = cvt.ToInt( getVal( dic, "NoRefreshSecond" ) );
|
||||
|
||||
_siteSetting.SmtpUrl = getVal( dic, "SmtpUrl" );
|
||||
_siteSetting.SmtpUser = getVal( dic, "SmtpUser" );
|
||||
_siteSetting.SmtpPwd = getVal( dic, "SmtpPwd" );
|
||||
_siteSetting.SmtpEnableSsl = cvt.ToBool( getVal( dic, "SmtpEnableSsl" ) );
|
||||
_siteSetting.EnableEmail = cvt.ToBool( getVal( dic, "EnableEmail" ) );
|
||||
|
||||
_siteSetting.CloseComment = cvt.ToBool( getVal( dic, "CloseComment" ) );
|
||||
|
||||
_siteSetting.UserDisplayName = cvt.ToInt(getVal(dic, "UserDisplayName"));
|
||||
_siteSetting.ValidateUserByMembership = cvt.ToBool(getVal(dic, "ValidateUserByMembership"));
|
||||
_siteSetting.DenyEditUserRealName = cvt.ToBool(getVal(dic, "DenyEditUserRealName"));
|
||||
_siteSetting.DenyEditUserTitle = cvt.ToBool(getVal(dic, "DenyEditUserTitle"));
|
||||
|
||||
_siteSetting.setValueAll( dic );
|
||||
}
|
||||
|
||||
private String getVal( Dictionary<String, String> dic, String key ) {
|
||||
String val;
|
||||
dic.TryGetValue( key, out val );
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
internal static readonly String siteconfigAbsPath = getSiteConfigAbsPath();
|
||||
|
||||
private static String getSiteConfigAbsPath() {
|
||||
return PathHelper.Map( strUtil.Join( cfgHelper.ConfigRoot, "site.config" ) );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using Zhaizj.Framework.Data;
|
||||
using Zhaizj.Framework.ORM;
|
||||
|
||||
namespace Zhaizj.Framework.DI {
|
||||
|
||||
/// <summary>
|
||||
/// 依赖注入中的配置项
|
||||
/// </summary>
|
||||
public class MapItem : CacheObject {
|
||||
|
||||
private Boolean _singleton = true;
|
||||
private Dictionary<String, object> _maps = new Dictionary<String, object>();
|
||||
|
||||
/// <summary>
|
||||
/// 容器创建对象的时候,是否以单例模式返回
|
||||
/// </summary>
|
||||
public Boolean Singleton {
|
||||
get { return _singleton; }
|
||||
set { _singleton = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 对象依赖注入关系的 map
|
||||
/// </summary>
|
||||
public Dictionary<String, object> Map {
|
||||
get { return _maps; }
|
||||
set { _maps = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 对象的 typeFullName
|
||||
/// </summary>
|
||||
public String Type { get; set; }
|
||||
|
||||
|
||||
internal void AddMap( String propertyName, MapItem item ) {
|
||||
AddMap( propertyName, item.Name );
|
||||
}
|
||||
|
||||
internal void AddMap( String propertyName, String injectBy ) {
|
||||
this.Map.Add( propertyName, injectBy );
|
||||
}
|
||||
|
||||
|
||||
private Object _obj;
|
||||
|
||||
[NotSave]
|
||||
internal Object TargetObject {
|
||||
get { return _obj; }
|
||||
set { _obj = value; }
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,423 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using Zhaizj.Framework.Reflection;
|
||||
using Zhaizj.Framework.Web.Mvc;
|
||||
using Zhaizj.Framework.Web.Mvc.Interface;
|
||||
|
||||
namespace Zhaizj.Framework.DI {
|
||||
|
||||
/// <summary>
|
||||
/// IOC 管理容器
|
||||
/// </summary>
|
||||
public class ObjectContext {
|
||||
|
||||
private static readonly ILog logger = LogManager.GetLogger( typeof( ObjectContext ) );
|
||||
|
||||
private static Object syncRoot = new object();
|
||||
private static volatile ObjectContext _instance;
|
||||
|
||||
private ObjectContext() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 容器的实例(单例)
|
||||
/// </summary>
|
||||
public static ObjectContext Instance {
|
||||
get {
|
||||
if (_instance == null) {
|
||||
lock (syncRoot) {
|
||||
if (_instance == null) {
|
||||
ObjectContext ctx = new ObjectContext();
|
||||
InitInject( ctx );
|
||||
_instance = ctx;
|
||||
}
|
||||
}
|
||||
}
|
||||
return _instance;
|
||||
}
|
||||
}
|
||||
|
||||
private static void InitInject( ObjectContext ctx ) {
|
||||
loadAssemblyAndTypes( ctx );
|
||||
resolveAndInject( ctx );
|
||||
addNamedObjects( ctx );
|
||||
}
|
||||
|
||||
private Dictionary<String, Assembly> _assemblyList = new Dictionary<String, Assembly>();
|
||||
private Dictionary<String, Type[]> _assemblyTypes = new Dictionary<String, Type[]>();
|
||||
private Dictionary<String, Type> _typeList = new Dictionary<String, Type>();
|
||||
|
||||
|
||||
private Dictionary<String, MapItem> _resolvedMap = new Dictionary<String, MapItem>();
|
||||
|
||||
private Hashtable _objectsContainerByName = new Hashtable();
|
||||
private Hashtable _objectsContainerByType = new Hashtable();
|
||||
|
||||
private Dictionary<String, IDto> _dtoList = new Dictionary<string, IDto>();
|
||||
|
||||
/// <summary>
|
||||
/// 所有纳入容器管理的程序集
|
||||
/// </summary>
|
||||
public Dictionary<String, Assembly> AssemblyList {
|
||||
get { return _assemblyList; }
|
||||
set { _assemblyList = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 所有程序集的 Dictionary
|
||||
/// </summary>
|
||||
public Dictionary<String, Type[]> AssemblyTypes {
|
||||
get { return _assemblyTypes; }
|
||||
set { _assemblyTypes = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 已经解析过的类型
|
||||
/// </summary>
|
||||
public Dictionary<String, MapItem> ResolvedMap {
|
||||
get { return _resolvedMap; }
|
||||
set { _resolvedMap = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 所有纳入容器管理的类型
|
||||
/// </summary>
|
||||
public Dictionary<String, Type> TypeList {
|
||||
get { return _typeList; }
|
||||
set { _typeList = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据名称罗列的对象表
|
||||
/// </summary>
|
||||
public Hashtable ObjectsByName {
|
||||
get { return _objectsContainerByName; }
|
||||
set { _objectsContainerByName = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据类型罗列的对象表
|
||||
/// </summary>
|
||||
public Hashtable ObjectsByType {
|
||||
get { return _objectsContainerByType; }
|
||||
set { _objectsContainerByType = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取所有的dto(工厂),用于创建dto对象
|
||||
/// </summary>
|
||||
public Dictionary<String, IDto> DtoList {
|
||||
get { return _dtoList; }
|
||||
set { _dtoList = value; }
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// 根据依赖注入的配置文件中的 name 获取对象
|
||||
/// </summary>
|
||||
/// <param name="objectName"></param>
|
||||
/// <returns></returns>
|
||||
public static Object GetByName( String objectName ) {
|
||||
|
||||
if (Instance.ResolvedMap.ContainsKey( objectName ) == false) return null;
|
||||
|
||||
MapItem item = Instance.ResolvedMap[objectName];
|
||||
if (item == null) return null;
|
||||
|
||||
if (item.Singleton)
|
||||
return Instance.ObjectsByName[objectName];
|
||||
else
|
||||
return createInstanceAndInject( item );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从缓存中取对象(有注入的就注入,没有注入的直接生成),结果是单例
|
||||
/// </summary>
|
||||
/// <param name="typeFullName"></param>
|
||||
/// <returns></returns>
|
||||
public static Object GetByType( String typeFullName ) {
|
||||
if (Instance.TypeList.ContainsKey( typeFullName ) == false) return null;
|
||||
Type t = Instance.TypeList[typeFullName];
|
||||
return GetByType( t );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从缓存中取对象(有注入的就注入,没有注入的直接生成),结果是单例
|
||||
/// </summary>
|
||||
/// <param name="t"></param>
|
||||
/// <returns></returns>
|
||||
public static Object GetByType( Type t ) {
|
||||
|
||||
if (t == null) return null;
|
||||
|
||||
Object result = Instance.ObjectsByType[t.FullName];
|
||||
|
||||
if (result == null) {
|
||||
|
||||
MapItem mapItem = getMapItemByType( t );
|
||||
if (mapItem != null) {
|
||||
result = createInstanceAndInject( mapItem );
|
||||
}
|
||||
else {
|
||||
result = rft.GetInstance( t );
|
||||
}
|
||||
|
||||
Instance.ObjectsByType[t.FullName] = result;
|
||||
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据type,不从缓存(pool)中取,而是全新创建实例(有注入的就注入,没有注入的直接生成),肯定不是单例
|
||||
/// </summary>
|
||||
/// <param name="t"></param>
|
||||
/// <returns></returns>
|
||||
public static Object CreateObject( Type t ) {
|
||||
if (t == null) return null;
|
||||
|
||||
MapItem mapItem = getMapItemByType( t );
|
||||
if (mapItem == null)
|
||||
return rft.GetInstance( t );
|
||||
else
|
||||
return createInstanceAndInject( mapItem );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据type,不从缓存(pool)中取,而是全新创建实例(有注入的就注入,没有注入的直接生成),肯定不是单例
|
||||
/// </summary>
|
||||
/// <param name="typeFullName"></param>
|
||||
/// <returns></returns>
|
||||
public static Object CreateObject( String typeFullName ) {
|
||||
if (Instance.TypeList.ContainsKey( typeFullName ) == false) return null;
|
||||
Type t = Instance.TypeList[typeFullName];
|
||||
return CreateObject( t );
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 根据type,不从缓存(pool)中取,而是全新创建实例(有注入的就注入,没有注入的直接生成),肯定不是单例
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>
|
||||
public static T Create<T>() {
|
||||
return (T)CreateObject( typeof( T ) );
|
||||
}
|
||||
|
||||
private static MapItem getMapItemByType( Type t ) {
|
||||
|
||||
Dictionary<String, MapItem> resolvedMap = Instance.ResolvedMap;
|
||||
foreach (KeyValuePair<String, MapItem> entry in resolvedMap) {
|
||||
MapItem item = entry.Value;
|
||||
if (t.FullName.Equals( item.Type )) return item;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Object createInstanceAndInject( MapItem item ) {
|
||||
Object currentObject = rft.GetInstance( item.TargetObject.GetType() );
|
||||
Dictionary<String, object> maps = item.Map;
|
||||
if (maps.Count > 0) {
|
||||
foreach (KeyValuePair<String, object> entry in maps) {
|
||||
Object propertyValue = GetByName( entry.Value.ToString() );
|
||||
if (propertyValue != null) {
|
||||
ReflectionUtil.SetPropertyValue( currentObject, entry.Key, propertyValue );
|
||||
}
|
||||
}
|
||||
}
|
||||
return currentObject;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
private static void loadAssemblyAndTypes( ObjectContext ctx ) {
|
||||
|
||||
String appSettings = cfgHelper.GetAppSettings( "InjectAssembly" );
|
||||
if (strUtil.IsNullOrEmpty( appSettings )) return;
|
||||
|
||||
String[] strArray = appSettings.Split( new char[] { ',' } );
|
||||
foreach (String asmStr in strArray) {
|
||||
|
||||
if (strUtil.IsNullOrEmpty( asmStr )) continue;
|
||||
String asmName = asmStr.Trim();
|
||||
Assembly assembly = loadAssemblyPrivate( asmName, ctx );
|
||||
findTypesPrivate( assembly, asmName, ctx );
|
||||
}
|
||||
}
|
||||
|
||||
private static Assembly loadAssemblyPrivate( String asmName, ObjectContext ctx ) {
|
||||
Assembly assembly = Assembly.Load( asmName );
|
||||
ctx.AssemblyList.Add( asmName, assembly );
|
||||
return assembly;
|
||||
}
|
||||
|
||||
private static void findTypesPrivate( Assembly assembly, String asmName, ObjectContext ctx ) {
|
||||
Type[] types = assembly.GetTypes();
|
||||
ctx.AssemblyTypes.Add( asmName, types );
|
||||
|
||||
foreach (Type type in types) {
|
||||
ctx.TypeList.Add( type.FullName, type );
|
||||
|
||||
if (rft.IsInterface( type, typeof( IDto ) )) {
|
||||
ctx.DtoList.Add( strUtil.TrimEnd( type.FullName, "Dto" ), (IDto)rft.GetInstance( type ) );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 加载程序集并返回此程序集,如果容器中已存在,则直接从容器中获取
|
||||
/// </summary>
|
||||
/// <param name="asmName"></param>
|
||||
/// <returns></returns>
|
||||
public static Assembly LoadAssembly( String asmName ) {
|
||||
Assembly assembly;// = Instance.AssemblyList[asmName];
|
||||
Instance.AssemblyList.TryGetValue( asmName, out assembly );
|
||||
if (assembly == null) {
|
||||
assembly = Assembly.Load( asmName );
|
||||
Instance.AssemblyList.Add( asmName, assembly );
|
||||
}
|
||||
return assembly;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 加载某程序集里的所有类型,如果容器中已存在,则直接从容器中获取
|
||||
/// </summary>
|
||||
/// <param name="asmName"></param>
|
||||
/// <returns></returns>
|
||||
public static Type[] FindTypes( String asmName ) {
|
||||
Type[] types;// = Instance.AssemblyTypes[asmName];
|
||||
Instance.AssemblyTypes.TryGetValue( asmName, out types );
|
||||
if (types == null) {
|
||||
types = LoadAssembly( asmName ).GetTypes();
|
||||
Instance.AssemblyTypes.Add( asmName, types );
|
||||
foreach (Type type in types) {
|
||||
Instance.TypeList.Add( type.FullName, type );
|
||||
}
|
||||
}
|
||||
return types;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------
|
||||
|
||||
private static void resolveAndInject( ObjectContext ctx ) {
|
||||
List<MapItem> maps = cdb.findAll<MapItem>();
|
||||
if (maps.Count <= 0) return;
|
||||
|
||||
Dictionary<String, MapItem> resolvedMap = new Dictionary<String, MapItem>();
|
||||
|
||||
logger.Info( "resolve item begin..." );
|
||||
resolveMapItem( maps, resolvedMap, ctx );
|
||||
|
||||
logger.Info( "inject Object begin..." );
|
||||
injectObjects( maps, resolvedMap );
|
||||
|
||||
ctx.ResolvedMap = resolvedMap;
|
||||
}
|
||||
|
||||
private static void resolveMapItem( List<MapItem> maps, Dictionary<String, MapItem> resolvedMap, ObjectContext ctx ) {
|
||||
foreach (MapItem oneMap in maps) {
|
||||
Type type;// = ctx.TypeList[oneMap.Type];
|
||||
ctx.TypeList.TryGetValue( oneMap.Type, out type );
|
||||
if (type == null) continue;
|
||||
logger.Info( "resolve:" + oneMap.Name );
|
||||
|
||||
if (oneMap.Singleton) {
|
||||
// ObjectsByType中存储的都是单例对象
|
||||
oneMap.TargetObject = checkByCache( type, ctx );
|
||||
}
|
||||
else {
|
||||
oneMap.TargetObject = rft.GetInstance( type );
|
||||
}
|
||||
resolvedMap[oneMap.Name] = oneMap;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private static Object checkByCache( Type t, ObjectContext ctx ) {
|
||||
if (ctx.ObjectsByType[t.FullName] == null) {
|
||||
ctx.ObjectsByType.Add( t.FullName, rft.GetInstance( t ) );
|
||||
}
|
||||
return ctx.ObjectsByType[t.FullName];
|
||||
}
|
||||
|
||||
|
||||
private static void injectObjects( List<MapItem> mapItems, Dictionary<String, MapItem> resolvedMap ) {
|
||||
foreach (MapItem item in mapItems) {
|
||||
logger.Info( "inject:" + item.Name );
|
||||
Dictionary<String, object> maps = item.Map;
|
||||
if (maps.Count <= 0) continue;
|
||||
|
||||
foreach (KeyValuePair<String, object> entry in maps) {
|
||||
logger.Info( "------inject key:" + entry.Key.ToString() );
|
||||
MapItem referencedItem;// = resolvedMap[entry.Value.ToString()];
|
||||
resolvedMap.TryGetValue( entry.Value.ToString(), out referencedItem );
|
||||
if (referencedItem != null) {
|
||||
ReflectionUtil.SetPropertyValue( item.TargetObject, entry.Key, referencedItem.TargetObject );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
|
||||
private static void addNamedObjects( ObjectContext ctx ) {
|
||||
Dictionary<String, MapItem> resolvedMap = ctx.ResolvedMap;
|
||||
Hashtable namedObjects = new Hashtable();
|
||||
foreach (KeyValuePair<String, MapItem> entry in resolvedMap) {
|
||||
MapItem item = entry.Value;
|
||||
namedObjects.Add( item.Name, item.TargetObject );
|
||||
}
|
||||
ctx.ObjectsByName = namedObjects;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 根据容器配置,将依赖关系注入到已创建的对象中
|
||||
/// </summary>
|
||||
/// <param name="obj"></param>
|
||||
public static void Inject( Object obj ) {
|
||||
|
||||
if (obj == null) return;
|
||||
|
||||
Type t = obj.GetType();
|
||||
|
||||
Dictionary<String, MapItem> resolvedMap = ObjectContext.Instance.ResolvedMap;
|
||||
|
||||
foreach (KeyValuePair<String, MapItem> pair in resolvedMap) {
|
||||
|
||||
MapItem item = pair.Value;
|
||||
if (item.Type.Equals( t.FullName ) == false) continue;
|
||||
|
||||
Dictionary<String, object> maps = item.Map;
|
||||
if (maps.Count <= 0) return;
|
||||
|
||||
injectObjectSingle( obj, resolvedMap, maps );
|
||||
return;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private static void injectObjectSingle( Object obj, Dictionary<String, MapItem> resolvedMap, Dictionary<String, object> maps ) {
|
||||
foreach (KeyValuePair<String, object> entry in maps) {
|
||||
|
||||
logger.Info( "------inject key:" + entry.Key.ToString() );
|
||||
MapItem referencedItem;
|
||||
resolvedMap.TryGetValue( entry.Value.ToString(), out referencedItem );
|
||||
if (referencedItem != null) {
|
||||
ReflectionUtil.SetPropertyValue( obj, entry.Key, referencedItem.TargetObject );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,129 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using Zhaizj.Framework.ORM;
|
||||
|
||||
namespace Zhaizj.Framework.Data {
|
||||
|
||||
/// <summary>
|
||||
/// 缓存对象,常驻内存,同时以json格式存储在磁盘中
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class CacheObject {
|
||||
|
||||
private int _id;
|
||||
private String _name;
|
||||
|
||||
/// <summary>
|
||||
/// 对象的 id
|
||||
/// </summary>
|
||||
public int Id {
|
||||
get { return _id; }
|
||||
set { _id = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 对象名称
|
||||
/// </summary>
|
||||
public String Name {
|
||||
get { return _name; }
|
||||
set { _name = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据 id 检索对象
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
public CacheObject findById( int id ) {
|
||||
return MemoryDB.FindById( this.GetType(), id );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检索出所有对象
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public IList findAll() {
|
||||
return MemoryDB.FindAll( this.GetType() );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据名称检索出对象列表
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
public IList findByName( String name ) {
|
||||
return this.findBy( "Name", name );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据属性名,检索出对象
|
||||
/// </summary>
|
||||
/// <param name="propertyName"></param>
|
||||
/// <param name="val"></param>
|
||||
/// <returns></returns>
|
||||
public IList findBy( String propertyName, Object val ) {
|
||||
findAll();
|
||||
return MemoryDB.FindBy( this.GetType(), propertyName, val );
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 插入数据:并对所有属性做索引,速度较慢
|
||||
/// </summary>
|
||||
public void insert() {
|
||||
MemoryDB.Insert( this );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 插入数据:只针对特定属性做索引,提高速度
|
||||
/// </summary>
|
||||
/// <param name="propertyName"></param>
|
||||
/// <param name="pValue"></param>
|
||||
public void insertByIndex( String propertyName, Object pValue ) {
|
||||
MemoryDB.InsertByIndex( this, propertyName, pValue );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 插入数据:针对若干属性做索引
|
||||
/// </summary>
|
||||
/// <param name="dic"></param>
|
||||
public void insertByIndex( Dictionary<String, Object> dic ) {
|
||||
MemoryDB.InsertByIndex( this, dic );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新数据
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public Result update() {
|
||||
return MemoryDB.Update( this );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新数据:只针对特性数据做索引
|
||||
/// </summary>
|
||||
/// <param name="dic"></param>
|
||||
public void updateByIndex( Dictionary<String, Object> dic ) {
|
||||
MemoryDB.updateByIndex( this, dic );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 不持久化,也不做索引
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public Result updateNoIndex() {
|
||||
return new Result();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除数据
|
||||
/// </summary>
|
||||
public void delete() {
|
||||
MemoryDB.Delete( this );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,480 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Specialized;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Web;
|
||||
|
||||
using Zhaizj.Framework.ORM;
|
||||
using Zhaizj.Framework.Serialization;
|
||||
using Zhaizj.Framework.Web;
|
||||
|
||||
namespace Zhaizj.Framework.Data {
|
||||
|
||||
internal class MemoryDB {
|
||||
|
||||
private static readonly ILog logger = LogManager.GetLogger( typeof( MemoryDB ) );
|
||||
|
||||
private static IDictionary objectList = Hashtable.Synchronized( new Hashtable() );
|
||||
private static IDictionary indexList = Hashtable.Synchronized( new Hashtable() );
|
||||
|
||||
public static IDictionary GetObjectsMap() {
|
||||
return objectList;
|
||||
}
|
||||
|
||||
public static IDictionary GetIndexMap() {
|
||||
return indexList;
|
||||
}
|
||||
|
||||
|
||||
private static Object objLock = new object();
|
||||
|
||||
private static Object chkLock = new object();
|
||||
|
||||
|
||||
private static IList GetObjectsByName( Type t ) {
|
||||
|
||||
if (isCheckFileDB( t )) {
|
||||
|
||||
lock (chkLock) {
|
||||
|
||||
if (isCheckFileDB( t )) {
|
||||
|
||||
loadDataFromFile( t );
|
||||
_hasCheckedFileDB[t] = true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
return (objectList[t.FullName] as IList);
|
||||
}
|
||||
|
||||
private static Hashtable _hasCheckedFileDB = new Hashtable();
|
||||
|
||||
private static Boolean isCheckFileDB( Type t ) {
|
||||
if (_hasCheckedFileDB[t] == null) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
private static void loadDataFromFile( Type t ) {
|
||||
if (Zhaizj.Framework.IO.File.Exists( getCachePath( t ) )) {
|
||||
IList list = getListWithIndex( Zhaizj.Framework.IO.File.Read( getCachePath( t ) ), t );
|
||||
objectList[t.FullName] = list;
|
||||
}
|
||||
else {
|
||||
objectList[t.FullName] = new ArrayList();
|
||||
}
|
||||
}
|
||||
|
||||
private static IList getListWithIndex( String jsonString, Type t ) {
|
||||
|
||||
IList list = new ArrayList();
|
||||
|
||||
if (strUtil.IsNullOrEmpty( jsonString )) return list;
|
||||
|
||||
List<object> lists = JsonParser.Parse( jsonString ) as List<object>;
|
||||
|
||||
foreach (Dictionary<String, object> map in lists) {
|
||||
|
||||
CacheObject obj = JSON.setValueToObject( t, map ) as CacheObject;
|
||||
int index = list.Add( obj );
|
||||
addIdIndex( t.FullName, obj.Id, index );
|
||||
makeIndexByInsert( obj );
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
private static void Serialize( Type t ) {
|
||||
Serialize( t, GetObjectsByName( t ) );
|
||||
}
|
||||
|
||||
private static void Serialize( Type t, IList list ) {
|
||||
String target = SimpleJsonString.ConvertList( list );
|
||||
if (strUtil.IsNullOrEmpty( target )) return;
|
||||
|
||||
String absolutePath = getCachePath( t );
|
||||
lock (objLock) {
|
||||
Zhaizj.Framework.IO.File.Write( absolutePath, target );
|
||||
}
|
||||
}
|
||||
|
||||
private static void UpdateObjects( String key, IList list ) {
|
||||
objectList[key] = list;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
internal static CacheObject FindById( Type t, int id ) {
|
||||
|
||||
IList list = GetObjectsByName( t );
|
||||
if (list.Count > 0) {
|
||||
int objIndex = getIndex( t.FullName, id );
|
||||
if (objIndex >= 0 && objIndex < list.Count) {
|
||||
return list[objIndex] as CacheObject;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
internal static IList FindBy( Type t, String propertyName, Object val ) {
|
||||
|
||||
String propertyKey = getPropertyKey( t.FullName, propertyName );
|
||||
NameValueCollection valueCollection = getValueCollection( propertyKey );
|
||||
|
||||
String ids = valueCollection[val.ToString()];
|
||||
if (strUtil.IsNullOrEmpty( ids )) return new ArrayList();
|
||||
|
||||
IList results = new ArrayList();
|
||||
String[] arrItem = ids.Split( ',' );
|
||||
foreach (String strId in arrItem) {
|
||||
int id = cvt.ToInt( strId );
|
||||
if (id < 0) continue;
|
||||
CacheObject obj = FindById( t, id );
|
||||
if (obj != null) results.Add( obj );
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
internal static IList FindAll( Type t ) {
|
||||
return new ArrayList( GetObjectsByName( t ) );
|
||||
}
|
||||
|
||||
internal static void Insert( CacheObject obj ) {
|
||||
|
||||
Type t = obj.GetType();
|
||||
String _typeFullName = t.FullName;
|
||||
|
||||
IList list = FindAll( t );
|
||||
obj.Id = getNextId( list );
|
||||
|
||||
int index = list.Add( obj );
|
||||
|
||||
addIdIndex( _typeFullName, obj.Id, index );
|
||||
UpdateObjects( _typeFullName, list );
|
||||
|
||||
makeIndexByInsert( obj );
|
||||
|
||||
if (isInMemory( t )) return;
|
||||
|
||||
Serialize( t );
|
||||
}
|
||||
|
||||
internal static void InsertByIndex( CacheObject obj, String propertyName, Object pValue ) {
|
||||
|
||||
Type t = obj.GetType();
|
||||
String _typeFullName = t.FullName;
|
||||
|
||||
IList list = FindAll( t );
|
||||
obj.Id = getNextId( list );
|
||||
int index = list.Add( obj );
|
||||
|
||||
addIdIndex( _typeFullName, obj.Id, index );
|
||||
UpdateObjects( _typeFullName, list );
|
||||
|
||||
makeIndexByInsert( obj, propertyName, pValue );
|
||||
|
||||
if (isInMemory( t )) return;
|
||||
|
||||
Serialize( t );
|
||||
}
|
||||
|
||||
internal static void InsertByIndex( CacheObject obj, Dictionary<String, Object> dic ) {
|
||||
|
||||
Type t = obj.GetType();
|
||||
String _typeFullName = t.FullName;
|
||||
|
||||
IList list = FindAll( t );
|
||||
obj.Id = getNextId( list );
|
||||
int index = list.Add( obj );
|
||||
|
||||
addIdIndex( _typeFullName, obj.Id, index );
|
||||
UpdateObjects( _typeFullName, list );
|
||||
|
||||
foreach (KeyValuePair<String, Object> kv in dic) {
|
||||
makeIndexByInsert( obj, kv.Key, kv.Value );
|
||||
}
|
||||
|
||||
if (isInMemory( t )) return;
|
||||
|
||||
Serialize( t );
|
||||
}
|
||||
|
||||
internal static Result Update( CacheObject obj ) {
|
||||
|
||||
Type t = obj.GetType();
|
||||
|
||||
makeIndexByUpdate( obj );
|
||||
|
||||
if (isInMemory( t )) return new Result();
|
||||
|
||||
try {
|
||||
Serialize( t );
|
||||
return new Result();
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
internal static Result updateByIndex( CacheObject obj, Dictionary<String, Object> dic ) {
|
||||
|
||||
Type t = obj.GetType();
|
||||
|
||||
makeIndexByUpdate( obj );
|
||||
|
||||
if (isInMemory( t )) return new Result();
|
||||
|
||||
try {
|
||||
Serialize( t );
|
||||
return new Result();
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
internal static void Delete( CacheObject obj ) {
|
||||
|
||||
Type t = obj.GetType();
|
||||
String _typeFullName = t.FullName;
|
||||
|
||||
makeIndexByDelete( obj );
|
||||
|
||||
IList list = FindAll( t );
|
||||
list.Remove( obj );
|
||||
UpdateObjects( _typeFullName, list );
|
||||
|
||||
deleteIdIndex( _typeFullName, obj.Id );
|
||||
|
||||
if (isInMemory( t )) return;
|
||||
|
||||
Serialize( t, list );
|
||||
}
|
||||
|
||||
private static int getNextId( IList list ) {
|
||||
if (list.Count == 0) return 1;
|
||||
CacheObject preObject = list[list.Count - 1] as CacheObject;
|
||||
return preObject.Id + 1;
|
||||
}
|
||||
|
||||
private static Boolean isInMemory( Type t ) {
|
||||
return rft.GetAttribute( t, typeof( NotSaveAttribute ) ) != null;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------
|
||||
|
||||
private static Object objIndexLock = new object();
|
||||
private static Object objIndexLockInsert = new object();
|
||||
private static Object objIndexLockUpdate = new object();
|
||||
private static Object objIndexLockDelete = new object();
|
||||
|
||||
private static void makeIndexByInsert( CacheObject cacheObject, String propertyName, Object pValue ) {
|
||||
if (cacheObject == null || pValue == null) return;
|
||||
Type t = cacheObject.GetType();
|
||||
String propertyKey = getPropertyKey( t.FullName, propertyName );
|
||||
lock (objIndexLock) {
|
||||
NameValueCollection valueCollection = getValueCollection( propertyKey );
|
||||
valueCollection.Add( pValue.ToString(), cacheObject.Id.ToString() );
|
||||
indexList[propertyKey] = valueCollection;
|
||||
}
|
||||
}
|
||||
|
||||
private static void makeIndexByInsert( CacheObject cacheObject ) {
|
||||
if (cacheObject == null) return;
|
||||
Type t = cacheObject.GetType();
|
||||
PropertyInfo[] properties = getProperties( t );
|
||||
foreach (PropertyInfo p in properties) {
|
||||
|
||||
String propertyKey = getPropertyKey( t.FullName, p.Name );
|
||||
lock (objIndexLockInsert) {
|
||||
NameValueCollection valueCollection = getValueCollection( propertyKey );
|
||||
addNewValueMap( valueCollection, cacheObject, p );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void makeIndexByUpdate( CacheObject cacheObject ) {
|
||||
if (cacheObject == null) return;
|
||||
Type t = cacheObject.GetType();
|
||||
PropertyInfo[] properties = getProperties( t );
|
||||
foreach (PropertyInfo p in properties) {
|
||||
|
||||
String propertyKey = getPropertyKey( t.FullName, p.Name );
|
||||
|
||||
lock (objIndexLockUpdate) {
|
||||
NameValueCollection valueCollection = getValueCollection( propertyKey );
|
||||
deleteOldValueIdMap( valueCollection, cacheObject.Id );
|
||||
addNewValueMap( valueCollection, cacheObject, p );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private static void makeIndexByUpdate( CacheObject cacheObject, String propertyName, Object pValue ) {
|
||||
if (cacheObject == null || pValue == null) return;
|
||||
Type t = cacheObject.GetType();
|
||||
|
||||
String propertyKey = getPropertyKey( t.FullName, propertyName );
|
||||
|
||||
lock (objIndexLockUpdate) {
|
||||
|
||||
NameValueCollection valueCollection = getValueCollection( propertyKey );
|
||||
deleteOldValueIdMap( valueCollection, cacheObject.Id );
|
||||
valueCollection.Add( pValue.ToString(), cacheObject.Id.ToString() );
|
||||
indexList[propertyKey] = valueCollection;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private static void makeIndexByDelete( CacheObject cacheObject ) {
|
||||
if (cacheObject == null) return;
|
||||
Type t = cacheObject.GetType();
|
||||
PropertyInfo[] properties = getProperties( t );
|
||||
foreach (PropertyInfo p in properties) {
|
||||
|
||||
String propertyKey = getPropertyKey( t.FullName, p.Name );
|
||||
lock (objIndexLockDelete) {
|
||||
NameValueCollection valueCollection = getValueCollection( propertyKey );
|
||||
deleteOldValueIdMap( valueCollection, cacheObject.Id );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static PropertyInfo[] getProperties( Type t ) {
|
||||
return t.GetProperties( BindingFlags.Public | BindingFlags.Instance );
|
||||
}
|
||||
|
||||
private static NameValueCollection getValueCollection( String propertyKey ) {
|
||||
NameValueCollection valueCollection = indexList[propertyKey] as NameValueCollection;
|
||||
if (valueCollection == null) valueCollection = new NameValueCollection();
|
||||
return valueCollection;
|
||||
}
|
||||
|
||||
private static void addNewValueMap( NameValueCollection valueCollection, CacheObject cacheObject, PropertyInfo p ) {
|
||||
|
||||
Attribute attr = rft.GetAttribute( p, typeof( NotSaveAttribute ) );
|
||||
if (attr != null) return;
|
||||
|
||||
String propertyKey = getPropertyKey( cacheObject.GetType().FullName, p.Name );
|
||||
|
||||
Object pValue = rft.GetPropertyValue( cacheObject, p.Name );
|
||||
if (pValue == null || strUtil.IsNullOrEmpty( pValue.ToString() )) return;
|
||||
|
||||
valueCollection.Add( pValue.ToString(), cacheObject.Id.ToString() );
|
||||
indexList[propertyKey] = valueCollection;
|
||||
}
|
||||
|
||||
// TODO 优化
|
||||
private static void deleteOldValueIdMap( NameValueCollection valueCollection, int oid ) {
|
||||
foreach (String key in valueCollection.AllKeys) {
|
||||
|
||||
String val = valueCollection[key];
|
||||
String[] arrItem = val.Split( ',' );
|
||||
StringBuilder result = new StringBuilder();
|
||||
foreach (String strId in arrItem) {
|
||||
int id = cvt.ToInt( strId );
|
||||
if (id == oid) continue;
|
||||
result.Append( strId );
|
||||
result.Append( "," );
|
||||
}
|
||||
String resultStr = result.ToString();
|
||||
if (strUtil.HasText( resultStr ))
|
||||
valueCollection[key] = resultStr.Trim().TrimEnd( ',' );
|
||||
else
|
||||
valueCollection.Remove( key );
|
||||
}
|
||||
}
|
||||
|
||||
private static String getPropertyKey( String typeFullName, String propertyName ) {
|
||||
return typeFullName + "_" + propertyName;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------- Id Index --------------------------------
|
||||
|
||||
private static IDictionary GetIdIndexMap( String key ) {
|
||||
if (objectList[key] == null) {
|
||||
objectList[key] = new Hashtable();
|
||||
}
|
||||
return (objectList[key] as IDictionary);
|
||||
}
|
||||
|
||||
private static void UpdateIdIndexMap( String key, IDictionary map ) {
|
||||
objectList[key] = map;
|
||||
}
|
||||
|
||||
private static void clearIdIndexMap( String key ) {
|
||||
objectList.Remove( key );
|
||||
}
|
||||
|
||||
|
||||
private static void addIdIndex( String typeFullName, int oid, int index ) {
|
||||
String key = getIdIndexMapKey( typeFullName );
|
||||
IDictionary indexMap = GetIdIndexMap( key );
|
||||
indexMap[oid] = index;
|
||||
UpdateIdIndexMap( key, indexMap );
|
||||
}
|
||||
private static void deleteIdIndex( String typeFullName, int oid ) {
|
||||
|
||||
String key = getIdIndexMapKey( typeFullName );
|
||||
|
||||
clearIdIndexMap( key );
|
||||
|
||||
IList results = objectList[typeFullName] as IList;
|
||||
foreach (CacheObject obj in results) {
|
||||
addIdIndex( typeFullName, obj.Id, results.IndexOf( obj ) );
|
||||
}
|
||||
|
||||
IDictionary indexMap = GetIdIndexMap( key );
|
||||
UpdateIdIndexMap( key, indexMap );
|
||||
}
|
||||
|
||||
private static int getIndex( String typeFullName, int oid ) {
|
||||
int result = -1;
|
||||
Object objIndex = GetIdIndexMap( getIdIndexMapKey( typeFullName ) )[oid];
|
||||
if (objIndex != null) {
|
||||
result = (int)objIndex;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static String getIdIndexMapKey( String typeFullName ) {
|
||||
return String.Format( "{0}_oid_index", typeFullName );
|
||||
}
|
||||
|
||||
//----------------------------------------------------------
|
||||
|
||||
private static String getCachePath( Type t ) {
|
||||
if (SystemInfo.IsWeb == false) {
|
||||
return getCacheFileName( t.FullName );
|
||||
}
|
||||
return getWebCacheFileName( t.FullName );
|
||||
}
|
||||
|
||||
private static String getCacheFileName( String name ) {
|
||||
return PathHelper.CombineAbs( new String[] {
|
||||
AppDomain.CurrentDomain.BaseDirectory,
|
||||
cfgHelper.FrameworkRoot,
|
||||
"data",
|
||||
name + fileExt
|
||||
} );
|
||||
}
|
||||
|
||||
private static String getWebCacheFileName( String name ) {
|
||||
|
||||
String rpath = strUtil.Join( cfgHelper.FrameworkRoot, "data" );
|
||||
rpath = strUtil.Join( rpath, name + fileExt );
|
||||
return PathHelper.Map( rpath );
|
||||
}
|
||||
|
||||
private static readonly String fileExt = ".config";
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Zhaizj.Framework.Config.DotNetConfig;
|
||||
using System.Configuration;
|
||||
|
||||
namespace Zhaizj.Framework.Data.Config
|
||||
{
|
||||
/// <summary>
|
||||
/// 数据库配置方式
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 配置文件格式和说明:
|
||||
/// <code>
|
||||
/// <configSections>
|
||||
/// <sectionGroup name="Zhaizj.Config" type="Zhaizj.Framework.Config.GroupHandler,Zhaizj.Framework">;
|
||||
/// <section name="DataBase" type="Zhaizj.Framework.Data.Config.SectionHandler, Zhaizj.Framework"/>;
|
||||
/// </sectionGroup>
|
||||
/// </configSections>
|
||||
/// <Zhaizj.Config>
|
||||
/// <log>
|
||||
/// <log/>
|
||||
/// <Zhaizj.Config/>
|
||||
/// ......
|
||||
/// </code>
|
||||
/// </remarks>
|
||||
public class SectionDataHandler : SectionBaseHandler<SectionDataHandler>
|
||||
{
|
||||
/// <summary>
|
||||
/// 配置数据库连接
|
||||
/// </summary>
|
||||
[ConfigurationProperty("ConnectionStringTable", DefaultValue = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=zhaizj.mdb")]
|
||||
public string ConnectionStringTable
|
||||
{
|
||||
get { return (string)this["ConnectionStringTable"]; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 配置数据库类型
|
||||
/// </summary>
|
||||
[ConfigurationProperty("DbType", DefaultValue = "access")]
|
||||
public string DbType
|
||||
{
|
||||
get { return (string)this["DbType"]; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 配置多数据库
|
||||
/// </summary>
|
||||
[ConfigurationProperty("Mapping", DefaultValue = "")]
|
||||
public string Mapping
|
||||
{
|
||||
get { return (string)this["Mapping"]; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///是否启用缓存
|
||||
/// </summary>
|
||||
[ConfigurationProperty("ApplicationCache", DefaultValue = "false")]
|
||||
public string ApplicationCache
|
||||
{
|
||||
get { return (string)this["ApplicationCache"]; }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///设置缓存时间-999 是永久缓存
|
||||
/// </summary>
|
||||
[ConfigurationProperty("ApplicationCacheMinutes", DefaultValue = "-999")]
|
||||
public string ApplicationCacheMinutes
|
||||
{
|
||||
get { return (string)this["ApplicationCacheMinutes"]; }
|
||||
}
|
||||
/// <summary>
|
||||
///缓存管理
|
||||
/// </summary>
|
||||
[ConfigurationProperty("ApplicationCacheManager", DefaultValue = "")]
|
||||
public string ApplicationCacheManager
|
||||
{
|
||||
get { return (string)this["ApplicationCacheManager"]; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
//程序集初始化
|
||||
/// </summary>
|
||||
[ConfigurationProperty("AssemblyList", DefaultValue = "Zhaizj.CoreApps")]
|
||||
public string AssemblyList
|
||||
{
|
||||
get { return (string)this["AssemblyList"]; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 拦截器
|
||||
/// </summary>
|
||||
[ConfigurationProperty("Interceptor", DefaultValue = "Zhaizj.CoreApps")]
|
||||
public string Interceptor
|
||||
{
|
||||
get { return (string)this["Interceptor"]; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 拼接代码
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public string GetDataConfig()
|
||||
{
|
||||
StringBuilder tagData = new StringBuilder();
|
||||
tagData.Append("{");
|
||||
tagData.Append("ConnectionStringTable : {default:\"" + ConnectionStringTable + "\"},");
|
||||
tagData.Append("DbType : { default:\"" + DbType + "\"},");
|
||||
tagData.Append("Mapping:[" + Mapping + "],");
|
||||
tagData.Append("ApplicationCache:" + ApplicationCache + ",");
|
||||
tagData.Append("ApplicationCacheMinutes:" + ApplicationCacheMinutes + ",");
|
||||
tagData.Append("ApplicationCacheManager:\"" + ApplicationCacheManager + "\",");
|
||||
tagData.Append("AssemblyList : [\"" + AssemblyList + "\"], Interceptor:[]");
|
||||
tagData.Append("}");
|
||||
return tagData.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Zhaizj.Framework
|
||||
{
|
||||
public enum TableName2
|
||||
{
|
||||
汽车品牌,
|
||||
汽车型号,
|
||||
颜色
|
||||
}
|
||||
|
||||
public enum DictEnum
|
||||
{
|
||||
结算方式 = 85,
|
||||
消费优惠 = 89,
|
||||
客户类型 = 1,
|
||||
提醒类型 = 102,
|
||||
默认类型 = -1,
|
||||
套餐类型 = 2,
|
||||
颜色 = 12,
|
||||
地区简码 = 15,
|
||||
单据类型 = 23,
|
||||
商品分类 = 35,
|
||||
单位 = 47,
|
||||
项目 = 37,
|
||||
商品 = 36,
|
||||
收支 = 74,
|
||||
收入 = 75,
|
||||
支出 = 76,
|
||||
其他收入 = 80,
|
||||
其他支出 = 84,
|
||||
客户详细 = 93,
|
||||
商品信息 = 107,
|
||||
性别 = 110,
|
||||
相关报表 = 113
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
using System;
|
||||
using System.Data;
|
||||
using System.IO;
|
||||
using System.Web;
|
||||
|
||||
using Zhaizj.Framework.Reflection;
|
||||
using Zhaizj.Framework.Web;
|
||||
using Zhaizj.Framework.Web.Mvc;
|
||||
|
||||
namespace Zhaizj.Framework.Data {
|
||||
|
||||
|
||||
internal class DatabaseBuilder {
|
||||
|
||||
public static String ConnectionStringPrefix = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=";
|
||||
private static readonly ILog logger = LogManager.GetLogger( typeof( DatabaseBuilder ) );
|
||||
|
||||
public static String BuildAccessDb4o() {
|
||||
String dbPath = getDbPath();
|
||||
BuildAccessDb4o( dbPath );
|
||||
return dbPath;
|
||||
}
|
||||
|
||||
public static void BuildAccessDb4o( String dbPath ) {
|
||||
String str = ConnectionStringPrefix + dbPath;
|
||||
logger.Info( "creating database : " + str );
|
||||
Object instanceFromProgId = ReflectionUtil.GetInstanceFromProgId( "ADOX.Catalog" );
|
||||
try {
|
||||
ReflectionUtil.CallMethod( instanceFromProgId, "Create", new object[] { str } );
|
||||
}
|
||||
catch (Exception exception) {
|
||||
logger.Info( "creating database error : " + exception.Message );
|
||||
LogManager.Flush();
|
||||
throw exception;
|
||||
}
|
||||
logger.Info( "create database ok" );
|
||||
}
|
||||
|
||||
//public static void Compact( String dbPath ) {
|
||||
// if (!File.Exists( dbPath )) {
|
||||
// throw new Exception( "database not found" );
|
||||
// }
|
||||
// IDbConnection connection = DbContext.getConnection();
|
||||
// if ((connection != null) && (connection.State == ConnectionState.Open)) {
|
||||
// connection.Close();
|
||||
// }
|
||||
// String sourceFileName = dbPath + ".bak";
|
||||
// ReflectionUtil.CallMethod( ReflectionUtil.GetInstanceFromProgId( "JRO.JetEngine" ), "CompactDatabase", new object[] { ConnectionStringPrefix + dbPath, ConnectionStringPrefix + sourceFileName } );
|
||||
// File.Copy( sourceFileName, dbPath, true );
|
||||
// File.Delete( sourceFileName );
|
||||
//}
|
||||
|
||||
private static String getDbPath() {
|
||||
DateTime now = DateTime.Now;
|
||||
String path = "Zhaizj.FrameworkDB_" + Guid.NewGuid().ToString().Replace( "-", "" ) + ".mdb";
|
||||
path = PathHelper.Map( path );
|
||||
return path;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Data.OleDb;
|
||||
using System.IO;
|
||||
|
||||
using Zhaizj.Framework.ORM;
|
||||
|
||||
namespace Zhaizj.Framework.Data {
|
||||
|
||||
internal class AccessDatabaseChecker : IDatabaseChecker {
|
||||
|
||||
private static readonly ILog logger = LogManager.GetLogger( typeof( AccessDatabaseChecker ) );
|
||||
|
||||
private String _connectionString;
|
||||
private List<String> existTables = new List<String>();
|
||||
|
||||
public String ConnectionString {
|
||||
get { return _connectionString; }
|
||||
set { _connectionString = value; }
|
||||
}
|
||||
|
||||
public DatabaseType DatabaseType {
|
||||
get { return DatabaseType.Access; }
|
||||
set { }
|
||||
}
|
||||
|
||||
public void CheckDatabase() {
|
||||
logger.Info( "begin check database" );
|
||||
if (strUtil.IsNullOrEmpty( _connectionString )) {
|
||||
logger.Info( "connection String is empty. begin to create access database and set connection string" );
|
||||
createDatabaseAndSaveConnectionString();
|
||||
}
|
||||
else {
|
||||
String connectionItem = DataFactory.GetDialect( DatabaseType.Access ).GetConnectionItem( _connectionString, ConnectionItemType.Database );
|
||||
if (strUtil.IsNullOrEmpty( connectionItem )) {
|
||||
logger.Info( "connection String is found, but database is empty. begin to create access database and set connection string" );
|
||||
createDatabaseAndSaveConnectionString();
|
||||
}
|
||||
else if (!File.Exists( connectionItem )) {
|
||||
logger.Info( "ConnectionString:" + _connectionString );
|
||||
logger.Info( "the database [" + connectionItem + "] is not found. begin to create access database and set connection string" );
|
||||
DatabaseBuilder.BuildAccessDb4o( connectionItem );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void CheckTable( MappingClass mapping, String db ) {
|
||||
logger.Info( "[access] begin check table" );
|
||||
|
||||
OleDbConnection connection = DataFactory.GetConnection( _connectionString, this.DatabaseType ) as OleDbConnection;
|
||||
connection.Open();
|
||||
IDbCommand cmd = new OleDbCommand();
|
||||
cmd.Connection = connection;
|
||||
object[] restrictions = new object[4];
|
||||
restrictions[3] = "TABLE";
|
||||
DataTable oleDbSchemaTable = connection.GetOleDbSchemaTable( OleDbSchemaGuid.Tables, restrictions );
|
||||
foreach (DataRow row in oleDbSchemaTable.Rows) {
|
||||
existTables.Add( row["TABLE_NAME"].ToString() );
|
||||
logger.Info( "table found£º" + row["TABLE_NAME"].ToString() );
|
||||
}
|
||||
existTables = new AccessTableBuilder().CheckMappingTableIsExist( cmd, db, existTables, mapping );
|
||||
connection.Close();
|
||||
}
|
||||
|
||||
private void createDatabaseAndSaveConnectionString() {
|
||||
_connectionString = DatabaseBuilder.ConnectionStringPrefix + DatabaseBuilder.BuildAccessDb4o();
|
||||
logger.Info( "connection String : " + _connectionString );
|
||||
DbConfig.SaveConnectionString( _connectionString );
|
||||
logger.Info( "the connection String is resetted" );
|
||||
}
|
||||
|
||||
|
||||
|
||||
public List<String> GetTables() {
|
||||
return existTables;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Zhaizj.Framework.ORM;
|
||||
|
||||
namespace Zhaizj.Framework.Data {
|
||||
|
||||
|
||||
internal interface IDatabaseChecker {
|
||||
|
||||
String ConnectionString { get; set; }
|
||||
DatabaseType DatabaseType { get; set; }
|
||||
|
||||
void CheckDatabase();
|
||||
void CheckTable( MappingClass mapping, String db );
|
||||
|
||||
List<String> GetTables();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
using System;
|
||||
using System.Data;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using Zhaizj.Framework.ORM;
|
||||
|
||||
namespace Zhaizj.Framework.Data {
|
||||
|
||||
|
||||
internal class MysqlDatabaseChecker : IDatabaseChecker {
|
||||
|
||||
private static readonly ILog logger = LogManager.GetLogger( typeof( MysqlDatabaseChecker ) );
|
||||
|
||||
private List<String> existTables = new List<String>();
|
||||
|
||||
private String _connectionString;
|
||||
|
||||
public String ConnectionString {
|
||||
get { return _connectionString; }
|
||||
set { _connectionString = value; }
|
||||
}
|
||||
|
||||
public DatabaseType DatabaseType {
|
||||
get { return DatabaseType.MySql; }
|
||||
set { }
|
||||
}
|
||||
|
||||
public void CheckDatabase() {
|
||||
|
||||
if (strUtil.IsNullOrEmpty( this._connectionString )) {
|
||||
throw new Exception( "connection string can not be empty" );
|
||||
}
|
||||
IDatabaseDialect dialect = DataFactory.GetDialect( DatabaseType.MySql );
|
||||
if (strUtil.IsNullOrEmpty( dialect.GetConnectionItem( this._connectionString, ConnectionItemType.Server ) )) {
|
||||
throw new Exception( "[mysql] server address is empty" );
|
||||
}
|
||||
if (strUtil.IsNullOrEmpty( dialect.GetConnectionItem( _connectionString, ConnectionItemType.Database ) )) {
|
||||
throw new Exception( "[mysql] database is empty" );
|
||||
}
|
||||
}
|
||||
|
||||
public void CheckTable( MappingClass mapping, String db ) {
|
||||
|
||||
logger.Info( "[mysql] begin check table" );
|
||||
IDbConnection connection = DataFactory.GetConnection( _connectionString, this.DatabaseType );
|
||||
connection.Open();
|
||||
|
||||
IDbCommand cmd = connection.CreateCommand();
|
||||
cmd.CommandText = "show tables";
|
||||
|
||||
IDataReader reader = cmd.ExecuteReader();
|
||||
|
||||
while (reader.Read()) {
|
||||
existTables.Add( reader[0].ToString() );
|
||||
logger.Info( "table found£º" + reader[0].ToString() );
|
||||
}
|
||||
|
||||
reader.Close();
|
||||
existTables = new MySqlTableBuilder().CheckMappingTableIsExist( cmd, db, existTables, mapping );
|
||||
|
||||
connection.Close();
|
||||
}
|
||||
|
||||
|
||||
public List<String> GetTables() {
|
||||
return existTables;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.SqlClient;
|
||||
|
||||
using Zhaizj.Framework.ORM;
|
||||
|
||||
namespace Zhaizj.Framework.Data {
|
||||
|
||||
|
||||
internal class SQLServerDatabaseChecker : IDatabaseChecker {
|
||||
|
||||
private static readonly ILog logger = LogManager.GetLogger( typeof( SQLServerDatabaseChecker ) );
|
||||
|
||||
private String _connectionString;
|
||||
private DatabaseType _databaseType;
|
||||
|
||||
public String ConnectionString {
|
||||
get { return _connectionString; }
|
||||
set { _connectionString = value; }
|
||||
}
|
||||
|
||||
public DatabaseType DatabaseType {
|
||||
get { return _databaseType; }
|
||||
set { _databaseType = value; }
|
||||
}
|
||||
|
||||
private List<String> existTables = new List<String>();
|
||||
|
||||
public void CheckDatabase() {
|
||||
if (strUtil.IsNullOrEmpty( _connectionString )) {
|
||||
throw new Exception( "[sqlserver] connection String is not found" );
|
||||
}
|
||||
IDatabaseDialect dialect = DataFactory.GetDialect( DatabaseType.SqlServer );
|
||||
if (strUtil.IsNullOrEmpty( dialect.GetConnectionItem( _connectionString, ConnectionItemType.Server ) )) {
|
||||
throw new Exception( "[sqlserver] address is empty" );
|
||||
}
|
||||
if (strUtil.IsNullOrEmpty( dialect.GetConnectionItem( _connectionString, ConnectionItemType.Database ) )) {
|
||||
throw new Exception( "[sqlserver] database is empty" );
|
||||
}
|
||||
}
|
||||
|
||||
public void CheckTable( MappingClass mapping, String db ) {
|
||||
logger.Info( "[sqlserver] begin check table" );
|
||||
SqlConnection connection = new SqlConnection( _connectionString );
|
||||
connection.Open();
|
||||
SqlCommand cmd = new SqlCommand();
|
||||
cmd.Connection = connection;
|
||||
cmd.CommandText = "SELECT OBJECT_NAME(id) as name FROM sysobjects WHERE xtype='U' AND OBJECTPROPERTY(id, 'IsMSShipped') = 0";
|
||||
SqlDataReader reader = cmd.ExecuteReader();
|
||||
while (reader.Read()) {
|
||||
existTables.Add( reader["name"].ToString() );
|
||||
logger.Info( "table found:" + reader["name"].ToString() );
|
||||
}
|
||||
reader.Close();
|
||||
existTables = new SqlServerTableBuilder().CheckMappingTableIsExist( cmd, db, existTables, mapping );
|
||||
|
||||
connection.Close();
|
||||
}
|
||||
|
||||
public List<String> GetTables() {
|
||||
return existTables;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,309 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
using Zhaizj.Framework.ORM;
|
||||
using Zhaizj.Framework.Reflection;
|
||||
using Zhaizj.Framework.Serialization;
|
||||
using Zhaizj.Framework.Web;
|
||||
using System.IO;
|
||||
using System.Web;
|
||||
using Zhaizj.Framework.IO;
|
||||
using Zhaizj.Framework.Data.Config;
|
||||
|
||||
namespace Zhaizj.Framework.Data {
|
||||
|
||||
/// <summary>
|
||||
/// 数据库连接字符串内容的封装
|
||||
/// </summary>
|
||||
public class ConnectionString {
|
||||
public String Name { get; set; }
|
||||
public String StringContent { get; set; }
|
||||
public DatabaseType DbType { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ORM 的数据库配置
|
||||
/// </summary>
|
||||
public class DbConfig {
|
||||
|
||||
private static readonly ILog logger = LogManager.GetLogger( typeof( DbConfig ) );
|
||||
|
||||
public DbConfig() {
|
||||
this.ConnectionStringTable = new Dictionary<String, object>();
|
||||
this.AssemblyList = new List<object>();
|
||||
this.DbType = new Dictionary<String, object>();
|
||||
this.IdType = Zhaizj.Framework.Data.IdType.Auto;
|
||||
this.Interceptor = new List<object>();
|
||||
this.IsCheckDatabase = true;
|
||||
this.ContextCache = true;
|
||||
this.Mapping = new List<object>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 默认数据库名称(值为default)
|
||||
/// </summary>
|
||||
public static readonly String DefaultDbName = "default";
|
||||
|
||||
/// <summary>
|
||||
/// 配置的缓存内容(单例模式缓存)
|
||||
/// </summary>
|
||||
public static DbConfig Instance = loadConfig( getConfigPath() );
|
||||
|
||||
/// <summary>
|
||||
/// 直接解析json的结果:多个数据库连接字符串(connectionString)的键值对
|
||||
/// </summary>
|
||||
public Dictionary<String, object> ConnectionStringTable { get; set; }
|
||||
|
||||
private Dictionary<String, ConnectionString> _connectionStringMap = new Dictionary<String, ConnectionString>();
|
||||
|
||||
/// <summary>
|
||||
/// 多个数据库连接字符串对象的map,值是ConnectionString对象(包括Name/StringContent/DbType)
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public Dictionary<String, ConnectionString> GetConnectionStringMap() {
|
||||
return _connectionStringMap;
|
||||
}
|
||||
|
||||
internal void SetConnectionStringMap( Dictionary<String, ConnectionString> cmap ) {
|
||||
_connectionStringMap = cmap;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 直接解析json的结果:数据库类型
|
||||
/// </summary>
|
||||
public Dictionary<String, object> DbType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 实体键值类型
|
||||
/// </summary>
|
||||
public String IdType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 自动键值
|
||||
/// </summary>
|
||||
[NotSerialize]
|
||||
public bool IsAutoId
|
||||
{
|
||||
get { return IdType.Equals(Zhaizj.Framework.Data.IdType.Auto, StringComparison.OrdinalIgnoreCase); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 直接解析json的结果:程序集列表
|
||||
/// </summary>
|
||||
public List<object> AssemblyList { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否坚持数据库,如果检查,则会将尚未创建的数据表自动创建
|
||||
/// </summary>
|
||||
public Boolean IsCheckDatabase { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 数据表的前缀(默认没有前缀)
|
||||
/// </summary>
|
||||
public String TablePrefix { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否开启一级缓存,默认开启,并且建议开启
|
||||
/// </summary>
|
||||
public Boolean ContextCache { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否开启二级缓存
|
||||
/// </summary>
|
||||
public Boolean ApplicationCache { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 二级缓存的时间(分钟)
|
||||
/// </summary>
|
||||
public int ApplicationCacheMinutes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 二级缓存管理程序,请填写类型(type)的全名(full name),比如 Zhaizj.Framework.somens.myCache;
|
||||
/// 如果不填写,则使用默认的System.Web.Caching
|
||||
/// </summary>
|
||||
public String ApplicationCacheManager { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ORM 的元数据文件名称,一般不需填写(建议不要填写)。如果为了提高网站启动时候的速度,可以填写。
|
||||
/// 系统会根据文件名自动生成元数据文件,可以避免以后网站启动过程中的反射,能略微提高启动速度;
|
||||
/// 文件名不包括路径(必须放在bin目录中),比如 Zhaizj.Framework.meta.dll
|
||||
/// </summary>
|
||||
public String MetaDLL { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 直接解析json的结果:数据表映射
|
||||
/// </summary>
|
||||
public List<object> Mapping { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 拦截器列表
|
||||
/// </summary>
|
||||
public List<object> Interceptor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 反射优化模式,目前只实现了 CodeDom 方式
|
||||
/// </summary>
|
||||
[NotSerialize]
|
||||
internal OptimizeMode OptimizeMode {
|
||||
get { return OptimizeMode.CodeDom; }
|
||||
set { }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取元数据库文件的绝对路径
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public String GetMetaDllAbsPath() {
|
||||
|
||||
if (strUtil.IsNullOrEmpty( this.MetaDLL )) return "";
|
||||
|
||||
String dllPath = this.MetaDLL;
|
||||
if (dllPath.ToLower().EndsWith( ".dll" ) == false)
|
||||
dllPath = dllPath + ".dll";
|
||||
|
||||
dllPath = Path.Combine( PathTool.GetBinDirectory(), dllPath );
|
||||
|
||||
|
||||
return dllPath;
|
||||
}
|
||||
|
||||
private Dictionary<String, MappingInfo> _mappings = new Dictionary<String, MappingInfo>();
|
||||
|
||||
private void addMapping( MappingInfo mi ) {
|
||||
_mappings.Add( mi.TypeName, mi );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取映射信息
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
internal Dictionary<String, MappingInfo> GetMappingInfo() {
|
||||
return _mappings;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
private static DbConfig loadConfig( String cfgPath ) {
|
||||
|
||||
String str = SectionDataHandler.Current.GetDataConfig();//file.Read( cfgPath );
|
||||
DbConfig dbc = JSON.ToObject<DbConfig>( str );
|
||||
|
||||
loadMappingInfo( dbc );
|
||||
checkConnectionString( dbc );
|
||||
|
||||
return dbc;
|
||||
}
|
||||
|
||||
private static void loadMappingInfo( DbConfig dbc ) {
|
||||
if (dbc.Mapping.Count == 0) return;
|
||||
foreach (Dictionary<String, object> dic in dbc.Mapping) {
|
||||
|
||||
MappingInfo mi = new MappingInfo();
|
||||
|
||||
if (dic.ContainsKey( "name" )) mi.TypeName = dic["name"].ToString();
|
||||
if (dic.ContainsKey( "database" )) mi.Database = dic["database"].ToString();
|
||||
if (dic.ContainsKey( "table" )) mi.Table = dic["table"].ToString();
|
||||
|
||||
dbc.addMapping( mi );
|
||||
}
|
||||
}
|
||||
|
||||
private static String getConfigPath() {
|
||||
return PathHelper.Map( strUtil.Join( cfgHelper.ConfigRoot, "orm.config" ) );
|
||||
}
|
||||
|
||||
private static void checkConnectionString( DbConfig result ) {
|
||||
|
||||
logger.Info( "checkConnectionString..." );
|
||||
|
||||
if (result.ConnectionStringTable == null) return;
|
||||
|
||||
Dictionary<String, ConnectionString> connStringMap = new Dictionary<String, ConnectionString>();
|
||||
|
||||
Dictionary<String, String> newString = new Dictionary<string, string>();
|
||||
foreach (KeyValuePair<String, object> kv in result.ConnectionStringTable) {
|
||||
|
||||
String connectionString = kv.Value.ToString();
|
||||
DatabaseType dbtype = getDbType( kv.Key, connectionString, result );
|
||||
|
||||
ConnectionString objConnString = new ConnectionString {
|
||||
Name = kv.Key,
|
||||
StringContent = connectionString,
|
||||
DbType = dbtype
|
||||
};
|
||||
|
||||
connStringMap.Add( kv.Key, objConnString );
|
||||
|
||||
logger.Info( "connectionString:" + connectionString );
|
||||
|
||||
IDatabaseDialect dialect = DataFactory.GetDialect( dbtype );
|
||||
|
||||
if ((dbtype == DatabaseType.Access)) {
|
||||
String connectionItem = dialect.GetConnectionItem( connectionString, ConnectionItemType.Database );
|
||||
logger.Info( "database path original:" + connectionItem );
|
||||
|
||||
if (IsRelativePath( connectionItem )) {
|
||||
connectionItem = PathHelper.Map( strUtil.Join( SystemInfo.ApplicationPath, connectionItem ) );
|
||||
logger.Info( "database path now:" + connectionItem );
|
||||
String newConnString = String.Format( "Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0}", connectionItem );
|
||||
|
||||
newString.Add( kv.Key, newConnString );
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (KeyValuePair<String, String> kv in newString) {
|
||||
result.ConnectionStringTable[kv.Key] = kv.Value;
|
||||
connStringMap[kv.Key].StringContent = kv.Value;
|
||||
}
|
||||
|
||||
result.SetConnectionStringMap( connStringMap );
|
||||
}
|
||||
|
||||
private static bool IsRelativePath( string connectionItem ) {
|
||||
return connectionItem.IndexOf( ":" ) < 0;
|
||||
}
|
||||
|
||||
private static DatabaseType getDbType( String dbname, String connectionString, DbConfig result ) {
|
||||
|
||||
foreach (KeyValuePair<String, Object> kv in result.DbType) {
|
||||
if (kv.Key == dbname) return DbTypeChecker.GetFromString( kv.Value.ToString() );
|
||||
}
|
||||
|
||||
DatabaseType dbtype = DbTypeChecker.GetDatabaseType( connectionString );
|
||||
return dbtype;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// 根据命名,获取数据库连接字符串
|
||||
/// </summary>
|
||||
/// <param name="db"></param>
|
||||
/// <returns></returns>
|
||||
public static String GetConnectionString( String db ) {
|
||||
if (DbConfig.Instance.ConnectionStringTable.ContainsKey( db ) == false)
|
||||
throw new Exception( lang.get( "dbNotExist" ) + ": " + db );
|
||||
return (String)DbConfig.Instance.ConnectionStringTable[db];
|
||||
}
|
||||
|
||||
|
||||
internal static void SaveConnectionString( String connectionString ) {
|
||||
|
||||
String cfgPath = getConfigPath();
|
||||
|
||||
if (DbConfig.Instance.ConnectionStringTable == null)
|
||||
DbConfig.Instance.ConnectionStringTable = new Dictionary<String, object>();
|
||||
|
||||
DbConfig.Instance.ConnectionStringTable[DefaultDbName] = connectionString;
|
||||
|
||||
String str = JsonString.ConvertObject( DbConfig.Instance, true );
|
||||
|
||||
file.Write( cfgPath, str );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
|
||||
namespace Zhaizj.Framework.Data {
|
||||
|
||||
internal class DbConst {
|
||||
|
||||
public static List<String> SqlKeyWords = getSqlKeyWords();
|
||||
|
||||
private static List<String> getSqlKeyWords() {
|
||||
|
||||
String[] strArray = "action/absolute/any/add/are/admindb/as/all/asc/alphanumeric/assertion/alter/authorization/alter/table/autoincrement/and/avg/as/begin/both/collation/between/column/binary/commit/bit/bit_length/comp/compression/connect/boolean/connection/constraint/constraints/by/container/byte/contains/cascade/convert/catalog/count/char/character/counter/char_length/create/character_length/currency/check/current_date/close/current_time/clustered/current_timestamp/coalesce/current_user/collate/cursor/database/disallow/date/disconnect/datetime/distinct/day/distinctrow/dec/decimal/domain/declare/double/delete/drop/desc/eqv/foreign/exclusiveconnect/from/exec/execute/exists/general/extract/grant/false/group/fetch/guid/first/having/float/float8/hour/float4/identity/input/ieeedouble/insensitive/ieeesingle/insert/ignore/insert/into/image/int/integer/integer4/imp/integer1/integer2/interval/index/indexcreatedb/is/inner/isolation/join/longtext/key/lower/language/match/last/max/left/memo/level/min/like/minute/logical/logical1/mod/long/money/longbinary/month/longchar/national/outer/nchar/output/nonclustered/owneraccess/not/pad/ntext/parameters/null/partial/number/password/numeric/percent/nvarchar/pivot/octet_length/position/oleobject/precision/on/prepare/open/primary/option/privileges/or/proc/procedure/order/public/smalldatetime/references/smallint/restrict/smallmoney/revoke/some/right/space/rollback/sql/schema/sqlcode/sqlerror/sqlstate/second/stdev/select/stdevp/selectschema/string/selectsecurity/substring/set/sum/short/sysname/single/system_user/size/table/updateowner/tableid/updatesecurity/temporary/upper/text/usage/time/user/timestamp/using/timezone_hour/value/timezone_minute/values/tinyint/var/to/varbinary/top/varchar/trailing/varp/transaction/varying/transform/view/translate/when/translation/whenever/trim/where/true/with/union/work/unique/xor/uniqueidentifier/year/unknown/yesno/update/zone/updateidentity".Split( new char[] { '/' } );
|
||||
|
||||
return new List<String>( strArray );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,225 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Threading;
|
||||
|
||||
using Zhaizj.Framework.Web;
|
||||
using Zhaizj.Framework.ORM;
|
||||
using Zhaizj.Framework.ORM.Caching;
|
||||
|
||||
namespace Zhaizj.Framework.Data {
|
||||
|
||||
/// <summary>
|
||||
/// 数据库上下文,主要用于获取数据库连接
|
||||
/// </summary>
|
||||
public class DbContext {
|
||||
|
||||
/// <summary>
|
||||
/// 获取数据库连接,返回的连接已经打开(open);在 mvc 框架中不用关闭,框架会自动关闭连接。
|
||||
/// 之所以要传入 Type,因为 ORM 支持多个数据库,不同的类型有可能映射到不同的数据库。
|
||||
/// </summary>
|
||||
/// <param name="t">实体的类型</param>
|
||||
/// <returns></returns>
|
||||
public static IDbConnection getConnection( Type t ) {
|
||||
return getConnection( Entity.GetInfo( t ) );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取数据库连接,返回的连接已经打开(open);在 mvc 框架中不用关闭,框架会自动关闭连接。
|
||||
/// 之所以要传入 EntityInfo,因为 ORM 支持多个数据库,不同的类型有可能映射到不同的数据库。
|
||||
/// </summary>
|
||||
/// <param name="et"></param>
|
||||
/// <returns></returns>
|
||||
public static IDbConnection getConnection( EntityInfo et ) {
|
||||
|
||||
String db = et.Database;
|
||||
String connectionString = DbConfig.GetConnectionString( db );
|
||||
|
||||
IDbConnection connection;
|
||||
getConnectionAll().TryGetValue( db, out connection );
|
||||
|
||||
if (connection == null) {
|
||||
connection = DataFactory.GetConnection( connectionString, et.DbType );
|
||||
|
||||
connection.Open();
|
||||
setConnection( db, connection );
|
||||
|
||||
if (shouldTransaction()) {
|
||||
IDbTransaction trans = connection.BeginTransaction();
|
||||
setTransaction( db, trans );
|
||||
}
|
||||
|
||||
return connection;
|
||||
}
|
||||
if (connection.State == ConnectionState.Closed) {
|
||||
connection.ConnectionString = connectionString;
|
||||
connection.Open();
|
||||
}
|
||||
return connection;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 关闭数据库连接。因为ORM支持多个数据库,所以所有可能的数据库连接都会一起关闭。
|
||||
/// </summary>
|
||||
public static void closeConnectionAll() {
|
||||
|
||||
ContextCache.Clear();
|
||||
|
||||
Dictionary<String, IDbConnection> dic = getConnectionAll();
|
||||
foreach (KeyValuePair<String, IDbConnection> kv in dic) {
|
||||
|
||||
IDbConnection connection = kv.Value;
|
||||
if ((connection != null) && (connection.State == ConnectionState.Open)) {
|
||||
connection.Close();
|
||||
connection.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
freeItem( _connectionKey );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// 获取所有的数据库连接
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static Dictionary<String, IDbConnection> getConnectionAll() {
|
||||
|
||||
Dictionary<String, IDbConnection> dic;
|
||||
|
||||
dic = CurrentRequest.getItem( _connectionKey ) as Dictionary<String, IDbConnection>;
|
||||
if (dic == null) {
|
||||
dic = new Dictionary<String, IDbConnection>();
|
||||
CurrentRequest.setItem( _connectionKey, dic );
|
||||
}
|
||||
return dic;
|
||||
}
|
||||
|
||||
private static Dictionary<String, IDbTransaction> getTransactionAll() {
|
||||
|
||||
Dictionary<String, IDbTransaction> dic;
|
||||
dic = CurrentRequest.getItem( _transactionKey ) as Dictionary<String, IDbTransaction>;
|
||||
if (dic == null) {
|
||||
dic = new Dictionary<String, IDbTransaction>();
|
||||
CurrentRequest.setItem( _transactionKey, dic );
|
||||
}
|
||||
return dic;
|
||||
}
|
||||
|
||||
private static void setConnection( String key, IDbConnection cn ) {
|
||||
getConnectionAll()[key] = cn;
|
||||
}
|
||||
|
||||
private static void setTransaction( String key, IDbTransaction trans ) {
|
||||
getTransactionAll()[key] = trans;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
public static void beginAndMarkTransactionAll() {
|
||||
CurrentRequest.setItem( _beginTransactionAll, true ); // 如果当前没有打开的数据库连接,则打上标记,等真正打开的时候启用事务
|
||||
beginTransactionAll();
|
||||
}
|
||||
|
||||
|
||||
private static bool shouldTransaction() {
|
||||
Object trans = CurrentRequest.getItem( _beginTransactionAll );
|
||||
if (trans == null) return false;
|
||||
return (Boolean)trans;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 针对所有数据库连接,开启数据库事务
|
||||
/// </summary>
|
||||
public static void beginTransactionAll() {
|
||||
Dictionary<String, IDbConnection> list = getConnectionAll();
|
||||
foreach (KeyValuePair<String, IDbConnection> kv in list) {
|
||||
IDbTransaction trans = kv.Value.BeginTransaction();
|
||||
setTransaction( kv.Key, trans );
|
||||
}
|
||||
}
|
||||
|
||||
public static void setTransaction( IDbCommand cmd ) {
|
||||
Dictionary<String, IDbTransaction> transTable = getTransactionAll();
|
||||
foreach (KeyValuePair<String, IDbTransaction> kv in transTable) {
|
||||
IDbTransaction trans = kv.Value;
|
||||
|
||||
if (cmd.Connection == trans.Connection) {
|
||||
cmd.Transaction = trans;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void clearTransactionAll() {
|
||||
Dictionary<String, IDbTransaction> dic = CurrentRequest.getItem( _transactionKey ) as Dictionary<String, IDbTransaction>;
|
||||
if (dic == null) return;
|
||||
dic.Clear();
|
||||
CurrentRequest.setItem( _transactionKey, dic );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 提交全部的数据库事务
|
||||
/// </summary>
|
||||
public static void commitAll() {
|
||||
Dictionary<String, IDbTransaction> transTable = getTransactionAll();
|
||||
foreach (KeyValuePair<String, IDbTransaction> kv in transTable) {
|
||||
IDbTransaction trans = kv.Value;
|
||||
if (trans != null && trans.Connection != null ) trans.Commit();
|
||||
}
|
||||
clearTransactionAll();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 回滚所有数据库事务
|
||||
/// </summary>
|
||||
public static void rollbackAll() {
|
||||
Dictionary<String, IDbTransaction> transTable = getTransactionAll();
|
||||
foreach (KeyValuePair<String, IDbTransaction> kv in transTable) {
|
||||
IDbTransaction trans = kv.Value;
|
||||
if (trans != null && trans.Connection != null) trans.Rollback();
|
||||
}
|
||||
clearTransactionAll();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
private static void freeItem( String key ) {
|
||||
if (!SystemInfo.IsWeb) {
|
||||
Thread.FreeNamedDataSlot( key );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
internal static IDictionary getContextCache() {
|
||||
|
||||
Object dic = CurrentRequest.getItem( _contextCacheKey );
|
||||
if (dic == null) {
|
||||
dic = new Hashtable();
|
||||
CurrentRequest.setItem( _contextCacheKey, dic );
|
||||
}
|
||||
return dic as IDictionary;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取存储在上下文中的 sql 执行次数
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static int getSqlCount() {
|
||||
|
||||
Object count = CurrentRequest.getItem( "sqlcount" );
|
||||
if (count == null) return 0;
|
||||
return cvt.ToInt( count );
|
||||
}
|
||||
|
||||
private static readonly String _beginTransactionAll = "__beginTransactionAll";
|
||||
private static readonly String _connectionKey = "__Zhaizj.FrameworkConnection";
|
||||
private static readonly String _transactionKey = "__Zhaizj.FrameworkDbTransaction";
|
||||
private static readonly String _contextCacheKey = "__contextCacheDictionary";
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright 2010 www.Zhaizj.Framework.com
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Web;
|
||||
using Zhaizj.Framework.Web;
|
||||
using Zhaizj.Framework.Web.Mvc;
|
||||
|
||||
namespace Zhaizj.Framework.Data {
|
||||
|
||||
/// <summary>
|
||||
/// access ÌØÊâÓï·¨´¦ÀíÆ÷
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class AccessDialect : IDatabaseDialect {
|
||||
|
||||
public String GetConnectionItem( String connectionString, ConnectionItemType connectionItem ) {
|
||||
String str = connectionItem.ToString().ToLower().Replace( "database", "data source" ).Replace( "userid", "user id" );
|
||||
String[] arrItem = connectionString.ToLower().Split( new char[] { ';' } );
|
||||
foreach (String item in arrItem) {
|
||||
if (item.Trim().ToLower().StartsWith( str )) {
|
||||
return item.Replace( str, "" ).Replace( "=", "" ).Replace( " ", "" );
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public String GetLimit( String sql, int limit ) {
|
||||
return sql.ToLower().Replace( "select ", "select top " + limit + " " );
|
||||
}
|
||||
|
||||
public String GetLimit( String sql) {
|
||||
return sql;
|
||||
}
|
||||
|
||||
public String GetTimeQuote() {
|
||||
return "#";
|
||||
}
|
||||
|
||||
public String GetParameter( String parameterName ) {
|
||||
return "?";
|
||||
}
|
||||
|
||||
public String GetParameterAdder( String parameterName ) {
|
||||
return ("@" + parameterName);
|
||||
}
|
||||
|
||||
public static String MapPath( String connectionString ) {
|
||||
if (SystemInfo.IsWeb==false) {
|
||||
return connectionString;
|
||||
}
|
||||
String connectionItem = new AccessDialect().GetConnectionItem( connectionString, ConnectionItemType.Database );
|
||||
String newValue = PathHelper.Map( connectionItem );
|
||||
return connectionString.Replace( connectionItem, newValue );
|
||||
}
|
||||
|
||||
public String Top {
|
||||
get { return "top"; }
|
||||
}
|
||||
|
||||
public string GetLeftQuote() {
|
||||
return "[";
|
||||
}
|
||||
|
||||
public string GetRightQuote() {
|
||||
return "]";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 2010 www.Zhaizj.Framework.com
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
|
||||
namespace Zhaizj.Framework.Data {
|
||||
|
||||
/// <summary>
|
||||
/// 各种数据库的特殊语法处理接口
|
||||
/// </summary>
|
||||
public interface IDatabaseDialect {
|
||||
|
||||
String GetConnectionItem( String connectionString, ConnectionItemType connectionItem );
|
||||
String GetLimit( String sql, int limit );
|
||||
String GetLimit( String sql );
|
||||
|
||||
String GetParameter( String parameterName );
|
||||
String GetParameterAdder( String parameterName );
|
||||
|
||||
String GetTimeQuote();
|
||||
|
||||
String GetLeftQuote();
|
||||
String GetRightQuote();
|
||||
|
||||
|
||||
String Top { get; }
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
using System;
|
||||
|
||||
namespace Zhaizj.Framework.Data {
|
||||
|
||||
/// <summary>
|
||||
/// mysql ÌØÊâÓï·¨´¦ÀíÆ÷
|
||||
/// </summary>
|
||||
public class MysqlDialect : IDatabaseDialect {
|
||||
|
||||
public String GetConnectionItem( String connectionString, ConnectionItemType connectionItem ) {
|
||||
return getConnectionItem( connectionString, connectionItem );
|
||||
}
|
||||
|
||||
|
||||
public static String getConnectionItem( String connStr, ConnectionItemType connectionItemType ) {
|
||||
|
||||
if (strUtil.IsNullOrEmpty( connStr )) throw new Exception( "mysql connection string is empty" );
|
||||
|
||||
String[] arrItems = connStr.ToLower().Split( ';' );
|
||||
|
||||
foreach (String item in arrItems) {
|
||||
|
||||
if (strUtil.IsNullOrEmpty( item )) continue;
|
||||
String[] arrPair = item.Split( '=' );
|
||||
if (arrPair.Length != 2) continue;
|
||||
|
||||
String key = arrPair[0].Trim();
|
||||
String val = arrPair[1].Trim();
|
||||
|
||||
if (keyEqual( key, connectionItemType )) return val;
|
||||
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
private static Boolean keyEqual( String key, ConnectionItemType connectionItemType ) {
|
||||
|
||||
if (connectionItemType == ConnectionItemType.Server) return key == "server";
|
||||
if (connectionItemType == ConnectionItemType.Database) return key == "database";
|
||||
if (connectionItemType == ConnectionItemType.UserId) return key == "user" || key == "uid" || key == "user id";
|
||||
if (connectionItemType == ConnectionItemType.Password) return key == "password" || key == "pwd";
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public String GetLimit( String sql, int limit ) {
|
||||
return (sql + " limit " + limit);
|
||||
}
|
||||
|
||||
public String GetLimit( String rSql ) {
|
||||
if (rSql == null) return null;
|
||||
|
||||
String sql = rSql.ToLower();
|
||||
if (sql.ToLower().IndexOf( " top " ) > 0) {
|
||||
|
||||
// selec top 10 * from
|
||||
// 10 * from
|
||||
String rMainSql = sql.Split( new String[] { " top " }, StringSplitOptions.None )[1].Trim();
|
||||
|
||||
String[] arrItem = rMainSql.Split( ' ' );
|
||||
int limit = cvt.ToInt( arrItem[0] );
|
||||
|
||||
String mainSql = strUtil.TrimStart( rMainSql, arrItem[0] );
|
||||
|
||||
|
||||
return this.GetLimit( "select " + mainSql, limit );
|
||||
}
|
||||
|
||||
return sql;
|
||||
}
|
||||
|
||||
public String GetTimeQuote() {
|
||||
return "'";
|
||||
}
|
||||
|
||||
public String GetParameter( String parameterName ) {
|
||||
return ("@" + parameterName);
|
||||
}
|
||||
|
||||
public String GetParameterAdder( String parameterName ) {
|
||||
return ("@" + parameterName);
|
||||
}
|
||||
|
||||
public String Top {
|
||||
get { return "limit"; }
|
||||
}
|
||||
|
||||
public string GetLeftQuote() {
|
||||
return "`";
|
||||
}
|
||||
|
||||
public string GetRightQuote() {
|
||||
return "`";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
using System;
|
||||
|
||||
namespace Zhaizj.Framework.Data {
|
||||
|
||||
/// <summary>
|
||||
/// sqlserver ÌØÊâÓï·¨´¦ÀíÆ÷
|
||||
/// </summary>
|
||||
public class SQLServerDialect : IDatabaseDialect {
|
||||
public String GetConnectionItem( String connectionString, ConnectionItemType connectionItem ) {
|
||||
String str = connectionItem.ToString().ToLower().Replace( "userid", "uid" ).Replace( "password", "pwd" );
|
||||
String[] strArray = connectionString.ToLower().Split( new char[] { ';' } );
|
||||
foreach (String item in strArray) {
|
||||
if (item.Trim().ToLower().StartsWith( str )) {
|
||||
return item.Replace( str, "" ).Replace( "=", "" ).Replace( " ", "" );
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public String GetTimeQuote() {
|
||||
return "'";
|
||||
}
|
||||
|
||||
public String GetLimit( String sql, int limit ) {
|
||||
return sql.ToLower().Replace( "select ", "select top " + limit + " " );
|
||||
}
|
||||
|
||||
public String GetLimit( String sql ) {
|
||||
return sql;
|
||||
}
|
||||
|
||||
public String GetParameter( String parameterName ) {
|
||||
return ("@" + parameterName);
|
||||
}
|
||||
|
||||
public String GetParameterAdder( String parameterName ) {
|
||||
return ("@" + parameterName);
|
||||
}
|
||||
|
||||
public String Top {
|
||||
get { return "top"; }
|
||||
}
|
||||
|
||||
public string GetLeftQuote() {
|
||||
return "[";
|
||||
}
|
||||
|
||||
public string GetRightQuote() {
|
||||
return "]";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,142 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Data;
|
||||
using System.IO;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Runtime.Serialization.Formatters.Binary;
|
||||
using System.Text;
|
||||
using System.Xml.Serialization;
|
||||
using Zhaizj.Framework.Log;
|
||||
|
||||
namespace Zhaizj.Framework.Data {
|
||||
|
||||
/// <summary>
|
||||
/// 简易数据库操作工具,兼容多种数据库,可执行sql,返回DataReader等
|
||||
/// </summary>
|
||||
public class EasyDB {
|
||||
|
||||
private static readonly ILog logger = LogManager.GetLogger( typeof( EasyDB ) );
|
||||
|
||||
public static int Execute( String sql, IDbConnection cn ) {
|
||||
logger.Info( LoggerUtil.SqlPrefix+"execute sql : " + sql );
|
||||
IDbCommand cmd = DataFactory.GetCommand( sql, cn );
|
||||
int result = cmd.ExecuteNonQuery();
|
||||
logger.Info( "affected : " + result );
|
||||
return result;
|
||||
}
|
||||
|
||||
public static IDataReader ExecuteReader( String sql, IDbConnection cn ) {
|
||||
logger.Info( LoggerUtil.SqlPrefix+"execute sql:" + sql );
|
||||
return DataFactory.GetCommand( sql, cn ).ExecuteReader();
|
||||
}
|
||||
|
||||
public static Object ExecuteScalar( String sql, IDbConnection cn ) {
|
||||
Object result = null;
|
||||
logger.Info( LoggerUtil.SqlPrefix+"execute sql:" + sql );
|
||||
result = DataFactory.GetCommand( sql, cn ).ExecuteScalar();
|
||||
if (result == DBNull.Value) {
|
||||
return null;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static DataTable ExecuteTable( String sql, IDbConnection cn ) {
|
||||
DataTable dataTable = new DataTable();
|
||||
logger.Info(LoggerUtil.SqlPrefix+ "execute sql:" + sql );
|
||||
DataFactory.GetAdapter( sql, cn ).Fill( dataTable );
|
||||
return dataTable;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------------------------
|
||||
|
||||
public static Hashtable LoadDicFromString( String targetString ) {
|
||||
Hashtable hashtable = new Hashtable();
|
||||
if (!strUtil.IsNullOrEmpty( targetString )) {
|
||||
String target = "";
|
||||
String[] strArray = targetString.Split( '=' );
|
||||
if (strArray.Length == 2) {
|
||||
target = strArray[1];
|
||||
}
|
||||
if (strUtil.HasText( target )) {
|
||||
foreach (String item in target.Split( '|' )) {
|
||||
String[] arr = item.Split( ':' );
|
||||
hashtable[arr[0]] = arr[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
return hashtable;
|
||||
}
|
||||
|
||||
public static Object LoadFromFile( String absFilePath ) {
|
||||
if (!Zhaizj.Framework.IO.File.Exists( absFilePath )) {
|
||||
return null;
|
||||
}
|
||||
IFormatter formatter = new BinaryFormatter();
|
||||
Stream serializationStream = new FileStream( absFilePath, FileMode.Open, FileAccess.Read, FileShare.Read );
|
||||
Object result = formatter.Deserialize( serializationStream );
|
||||
serializationStream.Close();
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Object LoadFromString( String targetString, Type targetType ) {
|
||||
XmlSerializer serializer = new XmlSerializer( targetType );
|
||||
TextReader textReader = new StringReader( targetString );
|
||||
Object result = serializer.Deserialize( textReader );
|
||||
textReader.Close();
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Object LoadFromXml( String filePath, Type targetType ) {
|
||||
if (!System.IO.File.Exists( filePath )) {
|
||||
return null;
|
||||
}
|
||||
XmlSerializer serializer = new XmlSerializer( targetType );
|
||||
Stream stream = new FileStream( filePath, FileMode.Open );
|
||||
Object result = serializer.Deserialize( stream );
|
||||
stream.Close();
|
||||
return result;
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------------------
|
||||
|
||||
public static String SaveDicToString( Hashtable tbl ) {
|
||||
if (tbl == null) {
|
||||
return null;
|
||||
}
|
||||
String str = "HashTable";
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.Append( str );
|
||||
builder.Append( "=" );
|
||||
foreach (DictionaryEntry entry in tbl) {
|
||||
builder.Append( entry.Key.ToString() + ":" + entry.Value.ToString() + "|" );
|
||||
}
|
||||
return builder.ToString().TrimEnd( new char[] { '|' } );
|
||||
}
|
||||
|
||||
public static void SaveToFile( Object target, String absFilePath ) {
|
||||
IFormatter formatter = new BinaryFormatter();
|
||||
Stream serializationStream = new FileStream( absFilePath, FileMode.Create, FileAccess.Write, FileShare.None );
|
||||
formatter.Serialize( serializationStream, target );
|
||||
serializationStream.Close();
|
||||
}
|
||||
|
||||
public static String SaveToString( Object target ) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
XmlSerializer serializer = new XmlSerializer( target.GetType() );
|
||||
TextWriter textWriter = new StringWriter( sb );
|
||||
serializer.Serialize( textWriter, target );
|
||||
textWriter.Close();
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public static void SaveToXml( String filePath, Object target ) {
|
||||
XmlSerializer serializer = new XmlSerializer( target.GetType() );
|
||||
TextWriter textWriter = new StreamWriter( filePath );
|
||||
serializer.Serialize( textWriter, target );
|
||||
textWriter.Close();
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
using System;
|
||||
|
||||
namespace Zhaizj.Framework.Data {
|
||||
|
||||
/// <summary>
|
||||
/// 数据库连接项的类型
|
||||
/// </summary>
|
||||
public enum ConnectionItemType {
|
||||
Server,
|
||||
UserId,
|
||||
Password,
|
||||
Database
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
using System;
|
||||
|
||||
namespace Zhaizj.Framework.Data {
|
||||
|
||||
/// <summary>
|
||||
/// Zhaizj.Framework ORM 支持的数据库类型
|
||||
/// </summary>
|
||||
public enum DatabaseType {
|
||||
Access,
|
||||
SqlServer,
|
||||
SqlServer2000,
|
||||
MySql,
|
||||
SQLite,
|
||||
Oracle,
|
||||
Other
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
using System;
|
||||
|
||||
namespace Zhaizj.Framework.Data {
|
||||
|
||||
/// <summary>
|
||||
/// 实体键值类型
|
||||
/// </summary>
|
||||
public static class IdType
|
||||
{
|
||||
/// <summary>
|
||||
/// 自动(默认类型)
|
||||
/// </summary>
|
||||
public static readonly string Auto="auto";
|
||||
|
||||
/// <summary>
|
||||
/// 整型
|
||||
/// </summary>
|
||||
public static readonly string Int = "int";
|
||||
|
||||
/// <summary>
|
||||
/// 长整型
|
||||
/// </summary>
|
||||
public static readonly string Long = "long";
|
||||
|
||||
/// <summary>
|
||||
/// Globally Unique Identifier(全球唯一标识符) 也称作 UUID(Universally Unique IDentifier) 。
|
||||
/// </summary>
|
||||
public static readonly string Guid = "guid";
|
||||
|
||||
/// <summary>
|
||||
/// 字符型
|
||||
/// </summary>
|
||||
public static readonly string String = "string";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using System;
|
||||
|
||||
namespace Zhaizj.Framework.Data {
|
||||
|
||||
/// <summary>
|
||||
/// 参数类型
|
||||
/// </summary>
|
||||
public enum ParameterType {
|
||||
Integer,
|
||||
Char,
|
||||
VarChar
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
|
||||
using System;
|
||||
using System.Data;
|
||||
using System.Data.Common;
|
||||
|
||||
namespace Zhaizj.Framework.Data {
|
||||
|
||||
/// <summary>
|
||||
/// 数据工厂,可以不用考虑数据库差异而获取 Connection, Command, DataAdapter
|
||||
/// </summary>
|
||||
public class DataFactory {
|
||||
|
||||
public static IDbConnection GetConnection( String connectionString, DatabaseType dbtype ) {
|
||||
return DbFactoryBase.Instance( dbtype ).GetConnection( connectionString );
|
||||
}
|
||||
|
||||
public static IDbCommand GetCommand( String CommandText, IDbConnection cn ) {
|
||||
return DbFactoryBase.Instance( cn ).GetCommand( CommandText );
|
||||
}
|
||||
|
||||
internal static IDatabaseChecker GetDatabaseChecker( DatabaseType dbtype ) {
|
||||
return DbFactoryBase.Instance( dbtype ).GetDatabaseChecker();
|
||||
}
|
||||
|
||||
public static IDatabaseDialect GetDialect( DatabaseType dbtype ) {
|
||||
return DbFactoryBase.Instance( dbtype ).GetDialect();
|
||||
}
|
||||
|
||||
public static Object SetParameter( IDbCommand cmd, String parameterName, Object parameterValue ) {
|
||||
return DbFactoryBase.Instance( cmd ).SetParameter( cmd, parameterName, parameterValue );
|
||||
}
|
||||
|
||||
public static DbDataAdapter GetAdapter( IDbCommand cmd ) {
|
||||
return DbFactoryBase.Instance( cmd ).GetAdapter();
|
||||
}
|
||||
|
||||
public static DbDataAdapter GetAdapter( String CommandText, IDbConnection cn ) {
|
||||
return DbFactoryBase.Instance( cn ).GetAdapter( CommandText );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
using System;
|
||||
using System.Data;
|
||||
using System.Data.Common;
|
||||
|
||||
namespace Zhaizj.Framework.Data {
|
||||
|
||||
/// <summary>
|
||||
/// 数据工厂抽象基类,可以不用考虑数据库差异而获取 Connection, Command, DataAdapter
|
||||
/// </summary>
|
||||
public abstract class DbFactoryBase {
|
||||
|
||||
public static DbFactoryBase Instance( String connectionString ) {
|
||||
DbFactoryBase result = Instance( DbTypeChecker.GetDatabaseType( connectionString ) );
|
||||
result.cn = result.GetConnection( connectionString );
|
||||
return result;
|
||||
}
|
||||
|
||||
public static DbFactoryBase Instance( IDbConnection cn ) {
|
||||
DbFactoryBase result = Instance( DbTypeChecker.GetDatabaseType( cn ) );
|
||||
result.cn = cn;
|
||||
return result;
|
||||
}
|
||||
|
||||
public static DbFactoryBase Instance( IDbCommand cmd ) {
|
||||
DbFactoryBase result = Instance( DbTypeChecker.GetDatabaseType( cmd ) );
|
||||
result.cmd = cmd;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public static DbFactoryBase Instance( DatabaseType dbtype ) {
|
||||
|
||||
if (dbtype == DatabaseType.SqlServer) return new MsSqlDbFactory();
|
||||
if (dbtype == DatabaseType.SqlServer2000) return new MsSqlDbFactory();
|
||||
if (dbtype == DatabaseType.Access) return new AccessFactory();
|
||||
if (dbtype == DatabaseType.MySql) return new MysqlFactory();
|
||||
if (dbtype == DatabaseType.Oracle) return new OracleFactory();
|
||||
|
||||
throw new Exception( lang.get( "dbNotSupport" ) );
|
||||
}
|
||||
|
||||
public abstract IDbConnection GetConnection( String connectionString );
|
||||
public abstract IDbCommand GetCommand( String CommandText );
|
||||
internal abstract IDatabaseChecker GetDatabaseChecker();
|
||||
public abstract IDatabaseDialect GetDialect();
|
||||
public abstract Object SetParameter( IDbCommand cmd, String parameterName, Object parameterValue );
|
||||
public abstract DbDataAdapter GetAdapter();
|
||||
public abstract DbDataAdapter GetAdapter( String CommandText );
|
||||
|
||||
|
||||
protected IDbConnection cn;
|
||||
protected IDbCommand cmd;
|
||||
|
||||
|
||||
protected virtual void setTransaction( IDbCommand cmd ) {
|
||||
DbContext.setTransaction( cmd );
|
||||
}
|
||||
|
||||
protected virtual Object processValue( Object parameterValue ) {
|
||||
|
||||
if (parameterValue is DateTime) {
|
||||
DateTime time = (DateTime)parameterValue;
|
||||
if ((time < new DateTime( 1800, 1, 1 )) || (time > new DateTime( 9000, 1, 1 ))) {
|
||||
parameterValue = DateTime.Now;
|
||||
}
|
||||
}
|
||||
else if (parameterValue is string) {
|
||||
parameterValue = parameterValue.ToString().Trim();
|
||||
}
|
||||
else if (parameterValue is int && (int)parameterValue == 0) {
|
||||
parameterValue = Convert.ToInt32( parameterValue );
|
||||
}
|
||||
|
||||
return parameterValue;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Data.SqlClient;
|
||||
using System.Data.OleDb;
|
||||
using System.Data.OracleClient;
|
||||
using System.Data;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Zhaizj.Framework.Data {
|
||||
|
||||
/// <summary>
|
||||
/// 检查数据库类型的工具
|
||||
/// </summary>
|
||||
public class DbTypeChecker {
|
||||
|
||||
|
||||
public static DatabaseType GetDatabaseType( IDbCommand cmd ) {
|
||||
if (cmd is SqlCommand) {
|
||||
return DatabaseType.SqlServer;
|
||||
}
|
||||
if (cmd is OleDbCommand) {
|
||||
return DatabaseType.Access;
|
||||
}
|
||||
if (cmd.GetType() == MysqlFactory.mySqlCommandType) {
|
||||
return DatabaseType.MySql;
|
||||
}
|
||||
if (cmd is OracleCommand) {
|
||||
return DatabaseType.Oracle;
|
||||
}
|
||||
return DatabaseType.Other;
|
||||
}
|
||||
|
||||
public static DatabaseType GetDatabaseType( IDbConnection cn ) {
|
||||
if (cn is OleDbConnection) {
|
||||
return DatabaseType.Access;
|
||||
}
|
||||
if (cn is SqlConnection) {
|
||||
return DatabaseType.SqlServer;
|
||||
}
|
||||
if (cn.GetType() == MysqlFactory.mySqlConnectionType) {
|
||||
return DatabaseType.MySql;
|
||||
}
|
||||
if (cn is OracleConnection) {
|
||||
return DatabaseType.Oracle;
|
||||
}
|
||||
return DatabaseType.Other;
|
||||
}
|
||||
|
||||
public static DatabaseType GetDatabaseType( String connectionString ) {
|
||||
if (!strUtil.IsNullOrEmpty( connectionString )) {
|
||||
if (connectionString.ToLower().IndexOf( "oledb" ) > 0) {
|
||||
return DatabaseType.Access;
|
||||
}
|
||||
if (connectionString.ToLower().IndexOf( "uid" ) > 0) {
|
||||
return DatabaseType.SqlServer;
|
||||
}
|
||||
if (connectionString.ToLower().IndexOf( "initial catalog" ) > 0) {
|
||||
return DatabaseType.SqlServer;
|
||||
}
|
||||
if (connectionString.ToLower().IndexOf( "user id" ) > 0) {
|
||||
return DatabaseType.MySql;
|
||||
}
|
||||
}
|
||||
return DatabaseType.Access;
|
||||
}
|
||||
|
||||
public static DatabaseType GetFromString( String typeString ) {
|
||||
|
||||
try {
|
||||
|
||||
return (DatabaseType)Enum.Parse( typeof( DatabaseType ), typeString, true );
|
||||
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new Exception( "数据库类型设置错误:" + ex.Message );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Data;
|
||||
using System.Data.SqlClient;
|
||||
using System.Data.Common;
|
||||
|
||||
namespace Zhaizj.Framework.Data {
|
||||
|
||||
/// <summary>
|
||||
/// sqlserver Êý¾Ý¹¤³§£¬»ñÈ¡ Connection, Command, DataAdapter
|
||||
/// </summary>
|
||||
public class MsSqlDbFactory : DbFactoryBase {
|
||||
|
||||
public override IDbConnection GetConnection( String connectionString ) {
|
||||
return new SqlConnection( connectionString );
|
||||
}
|
||||
|
||||
public override IDbCommand GetCommand( String CommandText ) {
|
||||
IDbCommand cmd = new SqlCommand();
|
||||
cmd.Connection = cn;
|
||||
cmd.CommandText = CommandText;
|
||||
setTransaction( cmd );
|
||||
return cmd;
|
||||
}
|
||||
|
||||
internal override IDatabaseChecker GetDatabaseChecker() {
|
||||
return new SQLServerDatabaseChecker();
|
||||
}
|
||||
|
||||
public override IDatabaseDialect GetDialect() {
|
||||
return new SQLServerDialect();
|
||||
}
|
||||
|
||||
public override Object SetParameter( IDbCommand cmd, String parameterName, Object parameterValue ) {
|
||||
|
||||
parameterValue = base.processValue( parameterValue );
|
||||
parameterName = new SQLServerDialect().GetParameterAdder( parameterName );
|
||||
|
||||
IDbDataParameter parameter = new SqlParameter( parameterName, parameterValue );
|
||||
cmd.Parameters.Add( parameter );
|
||||
|
||||
return parameterValue;
|
||||
}
|
||||
|
||||
public override DbDataAdapter GetAdapter() {
|
||||
return new SqlDataAdapter( (SqlCommand)cmd );
|
||||
}
|
||||
|
||||
public override DbDataAdapter GetAdapter( String CommandText ) {
|
||||
return new SqlDataAdapter( (SqlCommand)GetCommand( CommandText ) );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Data;
|
||||
using System.Data.Common;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Zhaizj.Framework.Data {
|
||||
|
||||
/// <summary>
|
||||
/// mysql Êý¾Ý¹¤³§£¬»ñÈ¡ Connection, Command, DataAdapter
|
||||
/// </summary>
|
||||
public class MysqlFactory : DbFactoryBase {
|
||||
|
||||
|
||||
public override IDbConnection GetConnection( String connectionString ) {
|
||||
return getMySqlConnection( connectionString );
|
||||
}
|
||||
|
||||
public override IDbCommand GetCommand( String CommandText ) {
|
||||
IDbCommand cmd = getMySqlCommand();
|
||||
cmd.Connection = cn;
|
||||
cmd.CommandText = CommandText;
|
||||
setTransaction( cmd );
|
||||
return cmd;
|
||||
}
|
||||
|
||||
internal override IDatabaseChecker GetDatabaseChecker() {
|
||||
return new MysqlDatabaseChecker();
|
||||
}
|
||||
|
||||
public override IDatabaseDialect GetDialect() {
|
||||
return new MysqlDialect();
|
||||
}
|
||||
|
||||
public override Object SetParameter( IDbCommand cmd, String parameterName, Object parameterValue ) {
|
||||
|
||||
parameterValue = base.processValue( parameterValue );
|
||||
parameterName = new MysqlDialect().GetParameterAdder( parameterName );
|
||||
|
||||
IDbDataParameter parameter = getMySqlParameter( parameterName, parameterValue );
|
||||
cmd.Parameters.Add( parameter );
|
||||
|
||||
return parameterValue;
|
||||
}
|
||||
|
||||
public override DbDataAdapter GetAdapter() {
|
||||
return getMySqlDataAdapter( cmd );
|
||||
}
|
||||
|
||||
public override DbDataAdapter GetAdapter( String CommandText ) {
|
||||
return getMySqlDataAdapter( GetCommand( CommandText ) );
|
||||
}
|
||||
|
||||
//-----------------------------------
|
||||
|
||||
private static IDbCommand getMySqlCommand() {
|
||||
return (rft.GetInstance( mySqlCommandType ) as IDbCommand);
|
||||
}
|
||||
|
||||
private static IDbConnection getMySqlConnection( String connectionString ) {
|
||||
return (rft.GetInstance( mySqlConnectionType, new object[] { connectionString } ) as IDbConnection);
|
||||
}
|
||||
|
||||
private static DbDataAdapter getMySqlDataAdapter( Object cmd ) {
|
||||
return (rft.GetInstance( mySqlDataAssembly.GetType( "MySql.Data.MySqlClient.MySqlDataAdapter" ), new object[] { cmd } ) as DbDataAdapter);
|
||||
}
|
||||
|
||||
private static IDbDataParameter getMySqlParameter( String parameterName, Object parameterValue ) {
|
||||
return (rft.GetInstance( mySqlDataAssembly.GetType( "MySql.Data.MySqlClient.MySqlParameter" ), new object[] { parameterName, parameterValue } ) as IDbDataParameter);
|
||||
}
|
||||
|
||||
public static Type mySqlCommandType {
|
||||
get { return mySqlDataAssembly.GetType( "MySql.Data.MySqlClient.MySqlCommand" ); }
|
||||
}
|
||||
|
||||
public static Type mySqlConnectionType {
|
||||
get { return mySqlDataAssembly.GetType( "MySql.Data.MySqlClient.MySqlConnection" ); }
|
||||
}
|
||||
|
||||
public static Assembly mySqlDataAssembly {
|
||||
get { return Assembly.Load( "MySql.Data" ); }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Data;
|
||||
using System.Data.OleDb;
|
||||
using System.Data.Common;
|
||||
|
||||
namespace Zhaizj.Framework.Data {
|
||||
|
||||
/// <summary>
|
||||
/// access Êý¾Ý¹¤³§£¬»ñÈ¡ Connection, Command, DataAdapter
|
||||
/// </summary>
|
||||
public class AccessFactory : DbFactoryBase {
|
||||
|
||||
|
||||
public override IDbConnection GetConnection( String connectionString ) {
|
||||
return new OleDbConnection( connectionString );
|
||||
}
|
||||
|
||||
public override IDbCommand GetCommand( String CommandText ) {
|
||||
IDbCommand cmd = new OleDbCommand();
|
||||
cmd.Connection = cn;
|
||||
cmd.CommandText = CommandText;
|
||||
setTransaction( cmd );
|
||||
return cmd;
|
||||
}
|
||||
|
||||
internal override IDatabaseChecker GetDatabaseChecker() {
|
||||
return new AccessDatabaseChecker();
|
||||
}
|
||||
|
||||
public override IDatabaseDialect GetDialect() {
|
||||
return new AccessDialect();
|
||||
}
|
||||
|
||||
public override Object SetParameter( IDbCommand cmd, String parameterName, Object parameterValue ) {
|
||||
|
||||
parameterValue = base.processValue( parameterValue );
|
||||
parameterName = new AccessDialect().GetParameterAdder( parameterName );
|
||||
|
||||
IDbDataParameter parameter;
|
||||
if (parameterValue is DateTime) {
|
||||
parameter = new OleDbParameter( parameterName, parameterValue.ToString() );
|
||||
}
|
||||
else {
|
||||
parameter = new OleDbParameter( parameterName, parameterValue );
|
||||
}
|
||||
cmd.Parameters.Add( parameter );
|
||||
|
||||
return parameterValue;
|
||||
|
||||
}
|
||||
|
||||
public override DbDataAdapter GetAdapter() {
|
||||
return new OleDbDataAdapter( (OleDbCommand)cmd );
|
||||
}
|
||||
|
||||
public override DbDataAdapter GetAdapter( String CommandText ) {
|
||||
return new OleDbDataAdapter( (OleDbCommand)GetCommand( CommandText ) );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Data;
|
||||
using System.Data.OracleClient;
|
||||
using System.Data.Common;
|
||||
|
||||
namespace Zhaizj.Framework.Data {
|
||||
|
||||
/// <summary>
|
||||
/// oracle Êý¾Ý¹¤³§£¬»ñÈ¡ Connection, Command, DataAdapter
|
||||
/// </summary>
|
||||
public class OracleFactory : DbFactoryBase {
|
||||
|
||||
public override IDbConnection GetConnection( String connectionString ) {
|
||||
return new OracleConnection( connectionString );
|
||||
}
|
||||
|
||||
public override IDbCommand GetCommand( String CommandText ) {
|
||||
IDbCommand cmd = new OracleCommand();
|
||||
cmd.Connection = cn;
|
||||
cmd.CommandText = CommandText;
|
||||
setTransaction( cmd );
|
||||
return cmd;
|
||||
}
|
||||
|
||||
// TODO
|
||||
internal override IDatabaseChecker GetDatabaseChecker() {
|
||||
throw new Exception( lang.get( "dbNotSupport" ) );
|
||||
}
|
||||
|
||||
// TODO
|
||||
public override IDatabaseDialect GetDialect() {
|
||||
throw new Exception( lang.get( "dbNotSupport" ) );
|
||||
}
|
||||
|
||||
public override Object SetParameter( IDbCommand cmd, String parameterName, Object parameterValue ) {
|
||||
|
||||
parameterValue = base.processValue( parameterValue );
|
||||
|
||||
// TODO
|
||||
//parameterName = new SQLServerDialect().GetParameterAdder( parameterName );
|
||||
|
||||
IDbDataParameter parameter = new OracleParameter( parameterName, parameterValue );
|
||||
cmd.Parameters.Add( parameter );
|
||||
|
||||
return parameterValue;
|
||||
}
|
||||
|
||||
public override DbDataAdapter GetAdapter() {
|
||||
return new OracleDataAdapter( (OracleCommand)cmd );
|
||||
}
|
||||
|
||||
public override DbDataAdapter GetAdapter( String CommandText ) {
|
||||
return new OracleDataAdapter( (OracleCommand)GetCommand( CommandText ) );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Collections;
|
||||
using Zhaizj.Framework.ORM;
|
||||
|
||||
namespace Zhaizj.Framework.Data {
|
||||
|
||||
internal class AccessTableBuilder : TableBuilderBase {
|
||||
|
||||
private Boolean isAddIdentityKey( Type t ) {
|
||||
if (OrmHelper.IsEntityBase( t.BaseType )) return true;
|
||||
if (t.BaseType.IsAbstract) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
protected override void addColumn_Decimal( EntityInfo entity, StringBuilder sb, EntityPropertyInfo ep, String columnName ) {
|
||||
if (ep.MoneyAttribute != null) {
|
||||
sb.Append( columnName );
|
||||
sb.Append( " currency default 0, " );
|
||||
}
|
||||
else {
|
||||
|
||||
DecimalAttribute da = ep.DecimalAttribute;
|
||||
if (da == null) throw new Exception( "DecimalAttribute not found=" + entity.FullName + "_" + ep.Name );
|
||||
|
||||
sb.Append( columnName );
|
||||
sb.Append( " decimal(" + da.Precision + "," + da.Scale + ") default 0, " );
|
||||
}
|
||||
}
|
||||
|
||||
protected override void addColumn_MiddleText( EntityInfo entity, StringBuilder sb, EntityPropertyInfo temP, string columnName ) {
|
||||
addColumn_LongText( entity, sb, columnName );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
using Zhaizj.Framework.ORM;
|
||||
|
||||
namespace Zhaizj.Framework.Data {
|
||||
|
||||
internal class MySqlTableBuilder : TableBuilderBase {
|
||||
|
||||
protected override void addColumn_PrimaryKey( EntityInfo entity, StringBuilder sb, IDictionary clsList ) {
|
||||
|
||||
sb.Append( " Id int unsigned not null auto_increment primary key, " );
|
||||
|
||||
}
|
||||
|
||||
protected override void addColumn_Int( StringBuilder sb, EntityPropertyInfo ep, String columnName ) {
|
||||
sb.Append( columnName );
|
||||
if (ep.Property.IsDefined( typeof( TinyIntAttribute ), false )) {
|
||||
sb.Append( " tinyint unsigned default 0, " );
|
||||
}
|
||||
else {
|
||||
sb.Append( " int unsigned default 0, " );
|
||||
}
|
||||
}
|
||||
|
||||
protected override void addColumn_LongText( EntityInfo entity, StringBuilder sb, String columnName ) {
|
||||
sb.Append( columnName );
|
||||
sb.Append( " text, " );
|
||||
}
|
||||
|
||||
protected override void addColumn_ShortText( StringBuilder sb, String columnName, int length ) {
|
||||
sb.Append( columnName );
|
||||
sb.Append( " varchar(" );
|
||||
sb.Append( length );
|
||||
sb.Append( "), " );
|
||||
}
|
||||
|
||||
protected override void addColumn_Decimal( EntityInfo entity, StringBuilder sb, EntityPropertyInfo ep, String columnName ) {
|
||||
|
||||
if (ep.MoneyAttribute != null) {
|
||||
sb.Append( columnName );
|
||||
sb.Append( " decimal(19, 4) default 0, " );
|
||||
}
|
||||
else {
|
||||
|
||||
DecimalAttribute da = ep.DecimalAttribute;
|
||||
if (da == null) throw new Exception( "DecimalAttribute not found=" + entity.FullName + "_" + ep.Name );
|
||||
|
||||
sb.Append( columnName );
|
||||
sb.Append( " decimal(" + da.Precision + "," + da.Scale + ") default 0, " );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
protected override void addColumn_Double( EntityInfo entity, StringBuilder sb, string columnName ) {
|
||||
sb.Append( columnName );
|
||||
sb.Append( " double default 0, " );
|
||||
}
|
||||
|
||||
|
||||
protected override void addColumn_Single( EntityInfo entity, StringBuilder sb, string columnName ) {
|
||||
sb.Append( columnName );
|
||||
sb.Append( " float default 0, " );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Zhaizj.Framework.Data {
|
||||
|
||||
internal class SqlServerTableBuilder : TableBuilderBase {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,226 @@
|
||||
using System;
|
||||
using System.Data;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
using Zhaizj.Framework.ORM;
|
||||
using Zhaizj.Framework.Log;
|
||||
|
||||
namespace Zhaizj.Framework.Data {
|
||||
|
||||
internal class TableBuilderBase {
|
||||
|
||||
|
||||
private static readonly ILog logger = LogManager.GetLogger( typeof( TableBuilderBase ) );
|
||||
|
||||
public List<String> CheckMappingTableIsExist( IDbCommand cmd, String db, List<String> existTables, MappingClass mapping ) {
|
||||
foreach (DictionaryEntry entry in mapping.ClassList) {
|
||||
EntityInfo entity = entry.Value as EntityInfo;
|
||||
if (entity.Database.Equals( db ) == false) continue;
|
||||
|
||||
if (!isTableCreated( existTables, entity )) {
|
||||
existTables = createTable( entity, cmd, existTables, mapping.ClassList );
|
||||
}
|
||||
}
|
||||
return existTables;
|
||||
}
|
||||
|
||||
private List<String> createTable( EntityInfo entity, IDbCommand cmd, List<String> existTables, IDictionary clsList ) {
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.AppendFormat( "Create Table {0} (", getFullName( entity.TableName, entity ) );
|
||||
addColumn_PrimaryKey( entity, sb, clsList );
|
||||
|
||||
addColumns( entity, sb );
|
||||
String str = sb.ToString().Trim().TrimEnd( new char[] { ',' } ) + " )";
|
||||
|
||||
cmd.CommandText = str;
|
||||
logger.Info( "create table:" + str );
|
||||
if (cmd.Connection == null) throw new Exception( "connection is null" );
|
||||
|
||||
if (cmd.Connection.State == ConnectionState.Closed) {
|
||||
cmd.Connection.Open();
|
||||
}
|
||||
|
||||
cmd.ExecuteNonQuery();
|
||||
|
||||
existTables.Add( entity.TableName );
|
||||
logger.Info( LoggerUtil.SqlPrefix + String.Format( "create table {0} ({1})", entity.TableName, entity.FullName ) );
|
||||
|
||||
return existTables;
|
||||
}
|
||||
|
||||
private void addColumns( EntityInfo entity, StringBuilder sb ) {
|
||||
for (int i = 0; i < entity.SavedPropertyList.Count; i++) {
|
||||
EntityPropertyInfo ep = entity.SavedPropertyList[i];
|
||||
String columnName = getFullName( ep.ColumnName, entity );
|
||||
if ((ep.SaveToDB && !ep.IsList) && !(ep.Name == "Id")) {
|
||||
addColumnSingle( entity, sb, ep, columnName );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void addColumnSingle( EntityInfo entity, StringBuilder sb, EntityPropertyInfo ep, String columnName ) {
|
||||
if (ep.Type == typeof( int )) {
|
||||
addColumn_Int( sb, ep, columnName );
|
||||
}
|
||||
else if (ep.Type == typeof( DateTime )) {
|
||||
addColumn_Time( sb, columnName );
|
||||
}
|
||||
else if (ep.Type == typeof( decimal )) {
|
||||
addColumn_Decimal( entity, sb, ep, columnName );
|
||||
}
|
||||
else if (ep.Type == typeof( double )) {
|
||||
addColumn_Double( entity, sb, columnName );
|
||||
}
|
||||
else if (ep.Type == typeof( float )) {
|
||||
addColumn_Single( entity, sb, columnName );
|
||||
}
|
||||
else if (ep.Type == typeof( String )) {
|
||||
addColumn_String( entity, sb, ep, columnName );
|
||||
}
|
||||
else if (ep.IsEntity) {
|
||||
addColumn_entity( sb, columnName );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
protected virtual void addColumn_PrimaryKey( EntityInfo entity, StringBuilder sb, IDictionary clsList ) {
|
||||
// 不是自动编号
|
||||
if (!DbConfig.Instance.IsAutoId || isAddIdentityKey( entity.Type ) == false) {
|
||||
sb.Append( " Id int primary key default 0, " );
|
||||
}
|
||||
else {
|
||||
sb.Append( " Id int identity(1,1) primary key, " );
|
||||
}
|
||||
}
|
||||
|
||||
private Boolean isAddIdentityKey( Type t ) {
|
||||
if (OrmHelper.IsEntityBase( t.BaseType )) return true;
|
||||
if (t.BaseType.IsAbstract) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
protected virtual void addColumn_Int( StringBuilder sb, EntityPropertyInfo ep, String columnName ) {
|
||||
sb.Append( columnName );
|
||||
if (ep.Property.IsDefined( typeof( TinyIntAttribute ), false )) {
|
||||
sb.Append( " tinyint default 0, " );
|
||||
}
|
||||
else {
|
||||
sb.Append( " int default 0, " );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected virtual void addColumn_Time( StringBuilder sb, String columnName ) {
|
||||
sb.Append( columnName );
|
||||
sb.Append( " DateTime, " );
|
||||
}
|
||||
|
||||
protected virtual void addColumn_Decimal( EntityInfo entity, StringBuilder sb, EntityPropertyInfo ep, String columnName ) {
|
||||
if (ep.MoneyAttribute != null) {
|
||||
sb.Append( columnName );
|
||||
sb.Append( " money default 0, " );
|
||||
}
|
||||
else {
|
||||
|
||||
DecimalAttribute da = ep.DecimalAttribute;
|
||||
if (da == null) throw new Exception( "DecimalAttribute not found=" + entity.FullName + "_" + ep.Name );
|
||||
|
||||
sb.Append( columnName );
|
||||
sb.Append( " decimal(" + da.Precision + "," + da.Scale + ") default 0, " );
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void addColumn_Double( EntityInfo entity, StringBuilder sb, string columnName ) {
|
||||
sb.Append( columnName );
|
||||
sb.Append( " float default 0, " );
|
||||
}
|
||||
|
||||
|
||||
protected virtual void addColumn_Single( EntityInfo entity, StringBuilder sb, string columnName ) {
|
||||
sb.Append( columnName );
|
||||
sb.Append( " real default 0, " );
|
||||
}
|
||||
|
||||
|
||||
protected virtual void addColumn_String( EntityInfo entity, StringBuilder sb, EntityPropertyInfo ep, String columnName ) {
|
||||
if (ep.LongTextAttribute != null) {
|
||||
addColumn_LongText( entity, sb, columnName );
|
||||
}
|
||||
else if (ep.SaveAttribute != null) {
|
||||
addColumn_ByColumnAttribute( entity, sb, ep, columnName );
|
||||
}
|
||||
else {
|
||||
addColumn_ShortText( sb, columnName, 250 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected virtual void addColumn_LongText( EntityInfo entity, StringBuilder sb, String columnName ) {
|
||||
sb.Append( columnName );
|
||||
sb.Append( " ntext, " );
|
||||
|
||||
}
|
||||
|
||||
protected virtual void addColumn_ShortText( StringBuilder sb, String columnName, int length ) {
|
||||
sb.Append( columnName );
|
||||
sb.Append( " nvarchar(" );
|
||||
sb.Append( length );
|
||||
sb.Append( "), " );
|
||||
}
|
||||
|
||||
|
||||
protected virtual void addColumn_ByColumnAttribute( EntityInfo entity, StringBuilder sb, EntityPropertyInfo ep, String columnName ) {
|
||||
if (ep.SaveAttribute.Length < 255) {
|
||||
addColumn_ShortText( sb, columnName, ep.SaveAttribute.Length );
|
||||
}
|
||||
else if ((ep.SaveAttribute.Length > 255) && (ep.SaveAttribute.Length < 4000)) {
|
||||
addColumn_MiddleText( entity, sb, ep, columnName );
|
||||
}
|
||||
else {
|
||||
addColumn_LongText( entity, sb, columnName );
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void addColumn_MiddleText( EntityInfo entity, StringBuilder sb, EntityPropertyInfo ep, String columnName ) {
|
||||
|
||||
addColumn_ShortText( sb, columnName, ep.SaveAttribute.Length );
|
||||
}
|
||||
|
||||
|
||||
protected virtual void addColumn_entity( StringBuilder sb, String columnName ) {
|
||||
sb.Append( columnName );
|
||||
sb.Append( " int default 0, " );
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
private String getFullName( String name, EntityInfo entity ) {
|
||||
if (DbConst.SqlKeyWords.Contains( name.ToLower() )) {
|
||||
String message = String.Format( "'{0}' is reserved word. Entity:{1}, Table:{2}", name, entity.FullName, entity.TableName );
|
||||
logger.Info( message );
|
||||
throw new Exception( message );
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
private Boolean isTableCreated( IList existTables, EntityInfo entity ) {
|
||||
for (int i = 0; i < existTables.Count; i++) {
|
||||
if (string.Compare( existTables[i].ToString(), entity.TableName.Replace( "[", "" ).Replace( "]", "" ), true ) == 0) {
|
||||
logger.Info( "table map : " + entity.FullName + " => " + existTables[i] );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
|
||||
namespace Zhaizj.Framework.Drawing {
|
||||
|
||||
/// <summary>
|
||||
/// 缩略图缩小方式(自动、根据宽度、根据高度、根据宽高、裁切)
|
||||
/// </summary>
|
||||
public enum SaveThumbnailMode {
|
||||
Auto,
|
||||
ByWidth,
|
||||
ByHeight,
|
||||
ByWidthHeight,
|
||||
Cut
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
|
||||
using System;
|
||||
|
||||
namespace Zhaizj.Framework.Drawing {
|
||||
|
||||
/// <summary>
|
||||
/// 缩略图大小类型(小、中等、大)
|
||||
/// </summary>
|
||||
public enum ThumbnailType {
|
||||
Small,
|
||||
Medium,
|
||||
Big
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Zhaizj.Framework.Drawing {
|
||||
|
||||
/// <summary>
|
||||
/// 水印位置(上面左部、上面中部、上面右部、下面左部、下面中部、下面右部)
|
||||
/// </summary>
|
||||
public enum WatermarkPosition {
|
||||
TopLeft,
|
||||
TopCenter,
|
||||
TopRight,
|
||||
BottomLeft,
|
||||
BottomCenter,
|
||||
BottomRight
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Drawing;
|
||||
|
||||
namespace Zhaizj.Framework.Drawing {
|
||||
|
||||
/// <summary>
|
||||
/// ×ÖÌå³ß´ç
|
||||
/// </summary>
|
||||
public class FontAndSize {
|
||||
|
||||
public Font font { get; set; }
|
||||
public SizeF size { get; set; }
|
||||
|
||||
public static FontAndSize GetValue( Graphics g, String text, String fontFamily, int fontSize, int srcWidth ) {
|
||||
|
||||
FontAndSize wfont = new FontAndSize();
|
||||
|
||||
Font font = null;
|
||||
SizeF size = new SizeF();
|
||||
|
||||
for (int i = fontSize; i > 6; i = i - 2) {
|
||||
font = new Font( fontFamily, i, FontStyle.Bold );
|
||||
size = g.MeasureString( text, font );
|
||||
if (size.Width <= srcWidth) break;
|
||||
}
|
||||
|
||||
wfont.font = font;
|
||||
wfont.size = size;
|
||||
|
||||
return wfont;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,397 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Drawing2D;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using System.Web;
|
||||
using Zhaizj.Framework.Web;
|
||||
using Zhaizj.Framework.Web.Utils;
|
||||
|
||||
|
||||
namespace Zhaizj.Framework.Drawing {
|
||||
|
||||
/// <summary>
|
||||
/// 图片常用操作
|
||||
/// </summary>
|
||||
public class Img {
|
||||
|
||||
private static readonly ILog logger = LogManager.GetLogger( typeof( Img ) );
|
||||
private static Random rd = new Random();
|
||||
|
||||
/// <summary>
|
||||
/// 删除图片以及缩略图。如果图片不存在,则忽略
|
||||
/// </summary>
|
||||
/// <param name="srcPath">相对网址</param>
|
||||
public static void DeleteImgAndThumb( String srcPath ) {
|
||||
|
||||
DeleteImgAndThumb( srcPath, Uploader.ThumbTypes );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除图片以及指定类型的缩略图。如果图片不存在,则忽略
|
||||
/// </summary>
|
||||
/// <param name="srcPath">相对网址</param>
|
||||
/// <param name="arrThumbType">多个缩略图类型</param>
|
||||
public static void DeleteImgAndThumb( String srcPath, ThumbnailType[] arrThumbType ) {
|
||||
|
||||
if (strUtil.IsNullOrEmpty( srcPath )) return;
|
||||
if (srcPath.ToLower().StartsWith( "http://" )) return;
|
||||
|
||||
String path = PathHelper.Map( srcPath );
|
||||
if (file.Exists( path ))
|
||||
Zhaizj.Framework.IO.File.Delete( path );
|
||||
|
||||
foreach (ThumbnailType ttype in arrThumbType) {
|
||||
|
||||
String pathThumb = PathHelper.Map( GetThumbPath( srcPath, ttype ) );
|
||||
if (file.Exists( pathThumb ))
|
||||
Zhaizj.Framework.IO.File.Delete( pathThumb );
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 彻底删除磁盘文件
|
||||
/// </summary>
|
||||
/// <param name="srcPath">相对路径</param>
|
||||
public static void DeleteFile( String srcPath ) {
|
||||
if (strUtil.IsNullOrEmpty( srcPath )) return;
|
||||
if (srcPath.ToLower().StartsWith( "http://" )) return;
|
||||
|
||||
String path = PathHelper.Map( srcPath );
|
||||
if (file.Exists( path ))
|
||||
Zhaizj.Framework.IO.File.Delete( path );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取图片的随机文件名(会添加日期文件夹和随机文件名),比如 2009-9-28/1530703343314547.jpg
|
||||
/// </summary>
|
||||
/// <remarks>如果日期文件夹不存在,则在磁盘上自动创建文件夹</remarks>
|
||||
/// <param name="pathName">图片存储的绝对路径</param>
|
||||
/// <param name="strContentType">图片类型</param>
|
||||
/// <returns>返回图片名称,包括所在文件夹,比如 2009-9-28/1530703343314547.jpg</returns>
|
||||
public static String GetPhotoName( String absPath, String strContentType ) {
|
||||
DateTime now = DateTime.Now;
|
||||
String strDir = getDirName( now );
|
||||
|
||||
String strRandom = rd.Next( 100000000, 999999999 ).ToString();
|
||||
|
||||
String strFile = now.Hour.ToString() + now.Minute.ToString() + now.Second.ToString() + now.Millisecond.ToString() + strRandom;
|
||||
strFile = strUtil.Join( strFile, GetImageExt( strContentType ), "." );
|
||||
|
||||
String fullDir = Path.Combine( absPath, strDir );
|
||||
if (!Directory.Exists( fullDir )) {
|
||||
Directory.CreateDirectory( fullDir );
|
||||
}
|
||||
return Path.Combine( strDir, strFile );
|
||||
}
|
||||
|
||||
//private static string getDirName( DateTime now ) {
|
||||
// return string.Format( "{0}-{1}-{2}", now.Year, now.Month, now.Day );
|
||||
//}
|
||||
|
||||
private static string getDirName( DateTime now ) {
|
||||
return string.Format( "{0}/{1}/{2}", now.Year, now.Month, now.Day );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取文件的随机文件名(会添加日期文件夹和随机文件名),比如 2009-9-28/1530703343314547.zip
|
||||
/// </summary>
|
||||
/// <remarks>如果日期文件夹不存在,则在磁盘上自动创建文件夹</remarks>
|
||||
/// <param name="pathName">存储路径</param>
|
||||
/// <param name="fileExt">文件类型</param>
|
||||
/// <returns>返回文件名称,包括所在文件夹,比如 2009-9-28/1530703343314547.zip</returns>
|
||||
public static String GetFileName( String pathName, String fileExt ) {
|
||||
DateTime now = DateTime.Now;
|
||||
String strDate = getDirName( now );
|
||||
|
||||
String strRandom = rd.Next( 100000000, 999999999 ).ToString();
|
||||
String strFile = now.Hour.ToString() + now.Minute.ToString() + now.Second.ToString() + now.Millisecond.ToString() + strRandom;
|
||||
strFile = strUtil.Join( strFile, fileExt, "." );
|
||||
|
||||
String path = Path.Combine( pathName, strDate );
|
||||
if (!Directory.Exists( path )) {
|
||||
Directory.CreateDirectory( path );
|
||||
}
|
||||
return Path.Combine( strDate, strFile );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据缩略图名称,获取原始图片名称
|
||||
/// </summary>
|
||||
/// <param name="thumbPath"></param>
|
||||
/// <returns></returns>
|
||||
public static String GetOriginalPath( String thumbPath ) {
|
||||
|
||||
String path = thumbPath.Trim();
|
||||
|
||||
String ext = Path.GetExtension( path );
|
||||
String pathWithoutExt = strUtil.TrimEnd( path, ext );
|
||||
|
||||
if (pathWithoutExt.EndsWith( "_s" )) {
|
||||
return strUtil.TrimEnd( pathWithoutExt, "_s" ) + ext;
|
||||
}
|
||||
|
||||
if (pathWithoutExt.EndsWith( "_m" )) {
|
||||
return strUtil.TrimEnd( pathWithoutExt, "_m" ) + ext;
|
||||
}
|
||||
|
||||
if (pathWithoutExt.EndsWith( "_b" )) {
|
||||
return strUtil.TrimEnd( pathWithoutExt, "_b" ) + ext;
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据原始图片名称,获取缩略图名称(最小的缩略图)
|
||||
/// </summary>
|
||||
/// <param name="srcPath"></param>
|
||||
/// <returns></returns>
|
||||
public static String GetThumbPath( Object srcPath ) {
|
||||
|
||||
if (srcPath == null) return null;
|
||||
if (strUtil.IsNullOrEmpty( srcPath.ToString() )) return null;
|
||||
return GetThumbPath( srcPath, ThumbnailType.Small );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据原始图片名称和缩略图类型,获取缩略图名称
|
||||
/// </summary>
|
||||
/// <param name="srcPath"></param>
|
||||
/// <param name="ttype"></param>
|
||||
/// <returns></returns>
|
||||
public static String GetThumbPath( Object srcPath, ThumbnailType ttype ) {
|
||||
|
||||
if (srcPath == null) return "";
|
||||
String path = srcPath.ToString();
|
||||
if (strUtil.IsNullOrEmpty( path )) return "";
|
||||
|
||||
String ext = Path.GetExtension( path );
|
||||
String pathWithoutExt = strUtil.TrimEnd( path, ext );
|
||||
|
||||
if (pathWithoutExt.EndsWith( "_s" )) pathWithoutExt = strUtil.TrimEnd( pathWithoutExt, "_s" );
|
||||
if (pathWithoutExt.EndsWith( "_b" )) pathWithoutExt = strUtil.TrimEnd( pathWithoutExt, "_b" );
|
||||
if (pathWithoutExt.EndsWith( "_m" )) pathWithoutExt = strUtil.TrimEnd( pathWithoutExt, "_m" );
|
||||
|
||||
String suffix = "_s";
|
||||
if (ttype == ThumbnailType.Medium)
|
||||
suffix = "_m";
|
||||
else if (ttype == ThumbnailType.Big)
|
||||
suffix = "_b";
|
||||
|
||||
return pathWithoutExt + suffix + ext;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 保存缩略图到磁盘(可指定宽度,默认自动缩放)
|
||||
/// </summary>
|
||||
/// <param name="srcPath"></param>
|
||||
/// <param name="destPath"></param>
|
||||
/// <param name="width"></param>
|
||||
public static void SaveThumbnail( String srcPath, String destPath, int width ) {
|
||||
SaveThumbnail( srcPath, destPath, width, width, SaveThumbnailMode.Auto );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 保存缩略图到磁盘(可指定宽高,默认自动缩放)
|
||||
/// </summary>
|
||||
/// <param name="srcPath"></param>
|
||||
/// <param name="destPath"></param>
|
||||
/// <param name="width"></param>
|
||||
/// <param name="height"></param>
|
||||
public static void SaveThumbnail( String srcPath, String destPath, int width, int height ) {
|
||||
SaveThumbnail( srcPath, destPath, width, height, SaveThumbnailMode.Auto );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 保存缩略图到磁盘(可指定宽高,可指定缩放模式)
|
||||
/// </summary>
|
||||
/// <param name="srcPath"></param>
|
||||
/// <param name="destPath"></param>
|
||||
/// <param name="width"></param>
|
||||
/// <param name="height"></param>
|
||||
/// <param name="mode"></param>
|
||||
public static void SaveThumbnail( String srcPath, String destPath, int width, int height, SaveThumbnailMode mode ) {
|
||||
|
||||
using (Image srcImg = Image.FromFile( srcPath )) {
|
||||
|
||||
ThumbSize t = getTargetSize( width, height, mode, srcImg );
|
||||
using (Bitmap newImg = new Bitmap( t.New.Width, t.New.Height )) {
|
||||
|
||||
using (Graphics g = Graphics.FromImage( newImg )) {
|
||||
g.InterpolationMode = InterpolationMode.High;
|
||||
g.SmoothingMode = SmoothingMode.HighQuality;
|
||||
g.Clear( Color.Transparent );
|
||||
g.DrawImage( srcImg, t.getNewRect(), t.getRect(), GraphicsUnit.Pixel );
|
||||
|
||||
try {
|
||||
newImg.Save( destPath, ImageFormat.Jpeg );
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw e;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取缩略图尺寸
|
||||
/// </summary>
|
||||
/// <param name="width"></param>
|
||||
/// <param name="height"></param>
|
||||
/// <param name="mode"></param>
|
||||
/// <param name="src"></param>
|
||||
/// <returns></returns>
|
||||
public static ThumbSize getTargetSize( int width, int height, SaveThumbnailMode mode, Image src ) {
|
||||
|
||||
ThumbSize t = new ThumbSize();
|
||||
t.Src = new Size( src.Width, src.Height );
|
||||
t.Point = new Point( 0, 0 );
|
||||
|
||||
if (mode == SaveThumbnailMode.ByWidth) {
|
||||
int newHeight = src.Height * width / src.Width;
|
||||
t.New = new Size( width, newHeight );
|
||||
return t;
|
||||
}
|
||||
else if (mode == SaveThumbnailMode.ByHeight) {
|
||||
int newWidth = src.Width * height / src.Height;
|
||||
t.New = new Size( newWidth, height );
|
||||
return t;
|
||||
}
|
||||
else if (mode == SaveThumbnailMode.ByWidthHeight) {
|
||||
t.New = new Size( width, height );
|
||||
return t;
|
||||
}
|
||||
else if (mode == SaveThumbnailMode.Cut) {
|
||||
return getCutSize( width, height, mode, src );
|
||||
}
|
||||
|
||||
return getAutoSize( width, height, mode, src );
|
||||
}
|
||||
|
||||
private static ThumbSize getAutoSize( int width, int height, SaveThumbnailMode mode, Image src ) {
|
||||
ThumbSize t = new ThumbSize();
|
||||
t.Src = new Size( src.Width, src.Height );
|
||||
t.Point = new Point( 0, 0 );
|
||||
|
||||
int newWidth = width;
|
||||
int newHeight = height;
|
||||
if ((double)src.Width / (double)src.Height > (double)width / (double)height)
|
||||
newHeight = src.Height * width / src.Width;
|
||||
else
|
||||
newWidth = src.Width * height / src.Height;
|
||||
t.New = new Size( newWidth, newHeight );
|
||||
|
||||
return t;
|
||||
|
||||
}
|
||||
|
||||
private static ThumbSize getCutSize( int width, int height, SaveThumbnailMode mode, Image src ) {
|
||||
|
||||
ThumbSize t = new ThumbSize();
|
||||
|
||||
if ((double)src.Width / (double)src.Height > (double)width / (double)height) {
|
||||
|
||||
int newWidth = src.Height * width / height;
|
||||
t.Src = new Size( newWidth, src.Height );
|
||||
t.New = new Size( width, height );
|
||||
t.Point = new Point( (src.Width - newWidth) / 2, 0 );
|
||||
}
|
||||
else {
|
||||
|
||||
int newHeight = src.Width * height / width;
|
||||
t.Src = new Size( src.Width, newHeight );
|
||||
t.New = new Size( width, height );
|
||||
t.Point = new Point( 0, (src.Height - newHeight) / 2 );
|
||||
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取图片的后缀名(不包括点号)
|
||||
/// </summary>
|
||||
/// <param name="strContentType"></param>
|
||||
/// <returns></returns>
|
||||
public static String GetImageExt( String strContentType ) {
|
||||
|
||||
if (strUtil.IsNullOrEmpty( strContentType )) return null;
|
||||
|
||||
String t = strContentType.ToLower();
|
||||
|
||||
logger.Info( "strContentType=>" + t );
|
||||
|
||||
if (t.Equals( ".gif" )) return "gif";
|
||||
if (t.Equals( ".bmp" )) return "bmp";
|
||||
if (t.Equals( ".png" )) return "png";
|
||||
if (t.Equals( ".jpg" )) return "jpg";
|
||||
if (t.Equals( ".jpeg" )) return "jpeg";
|
||||
|
||||
if (t.Equals( "gif" )) return "gif";
|
||||
if (t.Equals( "bmp" )) return "bmp";
|
||||
if (t.Equals( "png" )) return "png";
|
||||
if (t.Equals( "jpg" )) return "jpg";
|
||||
if (t.Equals( "jpeg" )) return "jpeg";
|
||||
|
||||
if (t.Equals( "image/gif")) return "gif";
|
||||
if (t.Equals( "image/bmp")) return "bmp";
|
||||
if (t.Equals( "image/tiff")) return "tiff";
|
||||
if (t.Equals( "image/x-icon")) return "icon";
|
||||
if (t.Equals( "image/x-png")) return "png"; // ie
|
||||
if (t.Equals( "image/png" )) return "png"; // firefox, google
|
||||
|
||||
if (t.Equals( "image/x-emf")) return "emf";
|
||||
if (t.Equals( "image/x-exif")) return "exif";
|
||||
if (t.Equals( "image/x-wmf")) return "wmf";
|
||||
if (t.Equals( "image/pjpeg")) return "jpg"; // ie6
|
||||
if (t.Equals( "image/jpg" )) return "jpg"; // ie8
|
||||
if (t.Equals( "image/jpeg" )) return "jpg"; // firefox, google
|
||||
|
||||
return "jpg";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取图片的类型
|
||||
/// </summary>
|
||||
/// <param name="strContentType"></param>
|
||||
/// <returns></returns>
|
||||
public static ImageFormat GetImageType( String strContentType ) {
|
||||
|
||||
if (strUtil.IsNullOrEmpty( strContentType )) return null;
|
||||
|
||||
String t = strContentType.ToLower();
|
||||
|
||||
if (t.Equals( ".gif" )) return ImageFormat.Gif;
|
||||
if (t.Equals( ".bmp" )) return ImageFormat.Bmp;
|
||||
if (t.Equals( ".png" )) return ImageFormat.Png;
|
||||
if (t.Equals( ".jpg" )) return ImageFormat.Jpeg;
|
||||
if (t.Equals( ".jpeg" )) return ImageFormat.Jpeg;
|
||||
|
||||
if (t.Equals( "gif" )) return ImageFormat.Gif;
|
||||
if (t.Equals( "bmp" )) return ImageFormat.Bmp;
|
||||
if (t.Equals( "png" )) return ImageFormat.Png;
|
||||
if (t.Equals( "jpg" )) return ImageFormat.Jpeg;
|
||||
if (t.Equals( "jpeg" )) return ImageFormat.Jpeg;
|
||||
|
||||
if (t.Equals( "image/pjpeg")) return ImageFormat.Jpeg;
|
||||
if (t.Equals( "image/gif")) return ImageFormat.Gif;
|
||||
if (t.Equals( "image/bmp")) return ImageFormat.Bmp;
|
||||
if (t.Equals( "image/tiff")) return ImageFormat.Tiff;
|
||||
if (t.Equals( "image/x-icon")) return ImageFormat.Icon;
|
||||
if (t.Equals( "image/x-png")) return ImageFormat.Png;
|
||||
if (t.Equals( "image/png" )) return ImageFormat.Png;
|
||||
if (t.Equals( "image/x-emf")) return ImageFormat.Emf;
|
||||
if (t.Equals( "image/x-exif")) return ImageFormat.Exif;
|
||||
if (t.Equals( "image/x-wmf")) return ImageFormat.Wmf;
|
||||
|
||||
return ImageFormat.MemoryBmp;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
using System.Drawing;
|
||||
|
||||
|
||||
namespace Zhaizj.Framework.Drawing {
|
||||
|
||||
/// <summary>
|
||||
/// ËõÂÔͼ³ß´ç
|
||||
/// </summary>
|
||||
public class ThumbSize {
|
||||
|
||||
public Size New { get; set; }
|
||||
public Size Src { get; set; }
|
||||
|
||||
public Point Point { get; set; }
|
||||
|
||||
public Rectangle getRect() {
|
||||
return new Rectangle( this.Point.X, this.Point.Y, this.Src.Width, this.Src.Height );
|
||||
}
|
||||
|
||||
public Rectangle getNewRect() {
|
||||
return new Rectangle( 0, 0, this.New.Width, this.New.Height );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Drawing2D;
|
||||
|
||||
namespace Zhaizj.Framework.Drawing {
|
||||
|
||||
/// <summary>
|
||||
/// 验证码工具
|
||||
/// </summary>
|
||||
public class ValidationCode {
|
||||
|
||||
/// <summary>
|
||||
/// 创建验证码,返回一个 Image 对象
|
||||
/// </summary>
|
||||
/// <param name="code"></param>
|
||||
/// <param name="width"></param>
|
||||
/// <param name="height"></param>
|
||||
/// <param name="fontFamily"></param>
|
||||
/// <returns></returns>
|
||||
public Image CreateImage( String code, int width, int height, String fontFamily ) {
|
||||
|
||||
Bitmap bm = new Bitmap( width, height );
|
||||
|
||||
using (Graphics g = Graphics.FromImage( bm )) {
|
||||
|
||||
g.SmoothingMode = SmoothingMode.AntiAlias;
|
||||
|
||||
HatchBrush brush = new HatchBrush( HatchStyle.SmallConfetti, Color.LightGray, Color.White );
|
||||
Rectangle rect = new Rectangle( 0, 0, width, height );
|
||||
g.FillRectangle( brush, rect );
|
||||
|
||||
int fontsize = rect.Height + 1;
|
||||
FontAndSize size = FontAndSize.GetValue( g, code, fontFamily, fontsize, bm.Width );
|
||||
|
||||
GraphicsPath gpath = getGraphicsPath( code, size.font, rect );
|
||||
|
||||
Color brushColor = ColorTranslator.FromHtml( "#000000" );
|
||||
brush = new HatchBrush( HatchStyle.Divot, brushColor, Color.DarkGray );
|
||||
g.FillPath( brush, gpath );
|
||||
|
||||
addRandomNoise( g, rect );
|
||||
|
||||
}
|
||||
return bm;
|
||||
}
|
||||
|
||||
private void addRandomNoise( Graphics g, Rectangle rect ) {
|
||||
|
||||
HatchBrush brush = new HatchBrush( HatchStyle.Weave, Color.LightGray, Color.White );
|
||||
|
||||
for (int i = 0; i < (int)(rect.Width * rect.Height / 30F); i++) {
|
||||
int x = rd.Next( rect.Width );
|
||||
int y = rd.Next( rect.Height );
|
||||
g.FillEllipse( brush, x, y, 2, 3 );
|
||||
}
|
||||
}
|
||||
|
||||
private Rectangle addRandomLine( Graphics g, Rectangle rect ) {
|
||||
int lineCount = rd.Next( 1, 8 );
|
||||
for (int i = 0; i < lineCount; i++) {
|
||||
|
||||
Point pt1 = new Point();
|
||||
pt1.X = rd.Next( rect.Width );
|
||||
pt1.Y = rd.Next( rect.Height );
|
||||
|
||||
Point pt2 = new Point();
|
||||
pt2.X = rd.Next( rect.Width );
|
||||
pt2.Y = rd.Next( rect.Height );
|
||||
|
||||
float width = rd.Next( 2 );
|
||||
|
||||
Pen p = new Pen( Color.Aqua, width );
|
||||
g.DrawLine( p, pt1, pt2 );
|
||||
}
|
||||
return rect;
|
||||
}
|
||||
|
||||
private StringFormat getFormat() {
|
||||
StringFormat format = new StringFormat();
|
||||
format.Alignment = StringAlignment.Center;
|
||||
format.LineAlignment = StringAlignment.Center;
|
||||
return format;
|
||||
}
|
||||
|
||||
private GraphicsPath getGraphicsPath( String code, Font font, Rectangle rect ) {
|
||||
|
||||
StringFormat format = getFormat();
|
||||
|
||||
GraphicsPath path = new GraphicsPath();
|
||||
path.AddString( code, font.FontFamily, (int)font.Style, font.Size, rect, format );
|
||||
|
||||
PointF[] points = getRandomPoint( rect );
|
||||
|
||||
Matrix matrix = new Matrix();
|
||||
matrix.Translate( 0F, 0F );
|
||||
|
||||
path.Warp( points, rect, matrix, WarpMode.Perspective, 0F );
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
private PointF[] getRandomPoint( Rectangle rect ) {
|
||||
float v = 4F;
|
||||
PointF[] points =
|
||||
{
|
||||
new PointF(rd.Next(rect.Width) / v, rd.Next(rect.Height) / v),
|
||||
new PointF(rect.Width - rd.Next(rect.Width) / v, rd.Next(rect.Height) / v),
|
||||
new PointF(rd.Next(rect.Width) / v, rect.Height - rd.Next(rect.Height) / v),
|
||||
new PointF(rect.Width - rd.Next(rect.Width) / v, rect.Height - rd.Next(rect.Height) / v)
|
||||
};
|
||||
return points;
|
||||
}
|
||||
|
||||
private Random rd = new Random();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,210 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
using System.Drawing;
|
||||
using System.Drawing.Drawing2D;
|
||||
using System.Drawing.Imaging;
|
||||
|
||||
namespace Zhaizj.Framework.Drawing {
|
||||
|
||||
/// <summary>
|
||||
/// 水印工具
|
||||
/// </summary>
|
||||
public class Watermark {
|
||||
|
||||
/// <summary>
|
||||
/// 将原始图片添加图片水印之后存储
|
||||
/// </summary>
|
||||
/// <param name="srcPath"></param>
|
||||
/// <param name="savePath"></param>
|
||||
/// <param name="watermarkPath"></param>
|
||||
/// <param name="wp"></param>
|
||||
public static void MakeByPic( String srcPath, String savePath, String watermarkPath, WatermarkPosition wp ) {
|
||||
|
||||
using (Image src = Image.FromFile( srcPath )) {
|
||||
using (Bitmap bm = new Bitmap( srcPath )) {
|
||||
using (Graphics g = Graphics.FromImage( bm )) {
|
||||
using (Image wm = Image.FromFile( watermarkPath )) {
|
||||
|
||||
ImageAttributes imgAttr = getImageAttributes();
|
||||
Rectangle rect = getPicRectangle( src, wm, wp );
|
||||
|
||||
g.DrawImage( wm, rect, 0, 0, wm.Width, wm.Height, GraphicsUnit.Pixel, imgAttr );
|
||||
|
||||
try {
|
||||
bm.Save( savePath );
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw e;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static ImageAttributes getImageAttributes() {
|
||||
|
||||
ImageAttributes imgAttr = new ImageAttributes();
|
||||
|
||||
ColorMap colorMap = new ColorMap();
|
||||
colorMap.OldColor = Color.FromArgb( 255, 0, 255, 0 );
|
||||
colorMap.NewColor = Color.FromArgb( 0, 0, 0, 0 );
|
||||
ColorMap[] remapTable = { colorMap };
|
||||
|
||||
imgAttr.SetRemapTable( remapTable, ColorAdjustType.Bitmap );
|
||||
|
||||
float[][] colorMatrixElements = {
|
||||
new float[] {1.0f, 0.0f, 0.0f, 0.0f, 0.0f},
|
||||
new float[] {0.0f, 1.0f, 0.0f, 0.0f, 0.0f},
|
||||
new float[] {0.0f, 0.0f, 1.0f, 0.0f, 0.0f},
|
||||
new float[] {0.0f, 0.0f, 0.0f, 0.3f, 0.0f},
|
||||
new float[] {0.0f, 0.0f, 0.0f, 0.0f, 1.0f}
|
||||
};
|
||||
|
||||
ColorMatrix wmColorMatrix = new ColorMatrix( colorMatrixElements );
|
||||
imgAttr.SetColorMatrix( wmColorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap );
|
||||
|
||||
return imgAttr;
|
||||
}
|
||||
|
||||
private static Rectangle getPicRectangle( Image src, Image wm, WatermarkPosition wp ) {
|
||||
|
||||
int x = 10;
|
||||
int y = 10;
|
||||
|
||||
if (wp == WatermarkPosition.TopLeft) {
|
||||
}
|
||||
else if (wp == WatermarkPosition.TopCenter) {
|
||||
x = src.Width / 2 - wm.Width / 2;
|
||||
y = 10;
|
||||
}
|
||||
else if (wp == WatermarkPosition.TopRight) {
|
||||
x = ((src.Width - wm.Width) - 10);
|
||||
y = 10;
|
||||
}
|
||||
else if (wp == WatermarkPosition.BottomLeft) {
|
||||
x = 10;
|
||||
y = src.Height - wm.Height - 10;
|
||||
}
|
||||
else if (wp == WatermarkPosition.BottomCenter) {
|
||||
x = src.Width / 2 - wm.Width / 2;
|
||||
y = src.Height - wm.Height - 10;
|
||||
}
|
||||
else if (wp == WatermarkPosition.BottomRight) {
|
||||
x = ((src.Width - wm.Width) - 10);
|
||||
y = src.Height - wm.Height - 10;
|
||||
}
|
||||
|
||||
return new Rectangle( x, y, wm.Width, wm.Height );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将原始图片添加文字水印之后存储
|
||||
/// </summary>
|
||||
/// <param name="srcPath"></param>
|
||||
/// <param name="savePath"></param>
|
||||
/// <param name="words"></param>
|
||||
/// <param name="wp"></param>
|
||||
/// <param name="fontSize"></param>
|
||||
public static void MakeByText( String srcPath, String savePath, String words, WatermarkPosition wp, int fontSize ) {
|
||||
|
||||
using (Image src = Image.FromFile( srcPath )) {
|
||||
using (Bitmap bm = new Bitmap( srcPath )) {
|
||||
using (Graphics g = Graphics.FromImage( bm )) {
|
||||
|
||||
FontAndSize fs = FontAndSize.GetValue( g, words, "arial", fontSize, src.Width );
|
||||
PointF p = getTextPoint( src, fs.size, wp );
|
||||
StringFormat sf = getStringFormat();
|
||||
|
||||
drawText( g, words, fs.font, p, sf );
|
||||
|
||||
try {
|
||||
bm.Save( savePath );
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw e;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static void drawText( Graphics g, String wmText, Font font, PointF p, StringFormat format ) {
|
||||
|
||||
SolidBrush brush = new SolidBrush( Color.FromArgb( 153, 255, 255, 255 ) );
|
||||
g.DrawString( wmText, font, brush, p, format );
|
||||
|
||||
SolidBrush brush2 = new SolidBrush( Color.FromArgb( 153, 0, 0, 0 ) );
|
||||
g.DrawString( wmText, font, brush2, new PointF( p.X + 1, p.Y + 1 ), format );
|
||||
}
|
||||
|
||||
private static StringFormat getStringFormat() {
|
||||
StringFormat StrFormat = new StringFormat();
|
||||
StrFormat.Alignment = StringAlignment.Center;
|
||||
return StrFormat;
|
||||
}
|
||||
|
||||
private static PointF getTextPoint( Image src, SizeF textSize, WatermarkPosition wp ) {
|
||||
|
||||
float x = textSize.Width / 2 + 5;
|
||||
float y = textSize.Height / 2 + 5;
|
||||
|
||||
int margin = 10;
|
||||
|
||||
if (wp == WatermarkPosition.TopLeft) {
|
||||
x = getLeftPosition( src, textSize, margin );
|
||||
y = getTopPosition( src, textSize, margin );
|
||||
}
|
||||
else if (wp == WatermarkPosition.TopCenter) {
|
||||
x = src.Width / 2;
|
||||
y = getTopPosition( src, textSize, margin );
|
||||
}
|
||||
else if (wp == WatermarkPosition.TopRight) {
|
||||
x = getRightPosition( src, textSize, margin );
|
||||
y = getTopPosition( src, textSize, margin );
|
||||
}
|
||||
else if (wp == WatermarkPosition.BottomLeft) {
|
||||
x = getLeftPosition( src, textSize, margin );
|
||||
y = getBottomPosition( src, textSize, margin );
|
||||
}
|
||||
else if (wp == WatermarkPosition.BottomCenter) {
|
||||
x = src.Width / 2;
|
||||
y = getBottomPosition( src, textSize, margin );
|
||||
}
|
||||
else if (wp == WatermarkPosition.BottomRight) {
|
||||
x = getRightPosition( src, textSize, margin );
|
||||
y = getBottomPosition( src, textSize, margin );
|
||||
}
|
||||
|
||||
return new PointF( x, y );
|
||||
}
|
||||
|
||||
private static float getLeftPosition( Image src, SizeF textSize, int margin ) {
|
||||
return textSize.Width / 2 + margin;
|
||||
}
|
||||
|
||||
private static float getTopPosition( Image src, SizeF textSize, int margin ) {
|
||||
return textSize.Height / 2 + margin / 2;
|
||||
}
|
||||
|
||||
private static float getRightPosition( Image src, SizeF textSize, int margin ) {
|
||||
float x = src.Width - margin * 2 - (textSize.Width / 2);
|
||||
return x;
|
||||
}
|
||||
|
||||
private static float getBottomPosition( Image src, SizeF textSize, int margin ) {
|
||||
float y = src.Height - margin * 2 - (textSize.Height / 2);
|
||||
return y;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace Zhaizj.Framework.IO {
|
||||
|
||||
/// <summary>
|
||||
/// 封装了文件常用操作方法
|
||||
/// </summary>
|
||||
public class File {
|
||||
|
||||
/// <summary>
|
||||
/// 读取文件的内容(采用UTF8编码)
|
||||
/// </summary>
|
||||
/// <param name="absolutePath">文件的绝对路径</param>
|
||||
/// <returns>文件的内容</returns>
|
||||
public static String Read( String absolutePath ) {
|
||||
return Read( absolutePath, Encoding.UTF8 );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 以某种编码方式,读取文件的内容
|
||||
/// </summary>
|
||||
/// <param name="absolutePath">文件的绝对路径</param>
|
||||
/// <param name="encoding">编码方式</param>
|
||||
/// <returns>文件的内容</returns>
|
||||
public static String Read( String absolutePath, Encoding encoding ) {
|
||||
using (StreamReader reader = new StreamReader( absolutePath, encoding )) {
|
||||
return reader.ReadToEnd();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取文件各行内容(采用UTF8编码),以数组形式返回
|
||||
/// </summary>
|
||||
/// <param name="absolutePath">文件的绝对路径</param>
|
||||
/// <returns>文件各行内容</returns>
|
||||
public static String[] ReadAllLines( String absolutePath ) {
|
||||
return ReadAllLines( absolutePath, Encoding.UTF8 );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 以某种编码方式,读取文件各行内容(采用UTF8编码),以数组形式返回
|
||||
/// </summary>
|
||||
/// <param name="absolutePath">文件的绝对路径</param>
|
||||
/// <param name="encoding">编码方式</param>
|
||||
/// <returns>文件各行内容</returns>
|
||||
public static String[] ReadAllLines( String absolutePath, Encoding encoding ) {
|
||||
ArrayList list = new ArrayList();
|
||||
using (StreamReader reader = new StreamReader( absolutePath, encoding )) {
|
||||
String str;
|
||||
while ((str = reader.ReadLine()) != null) {
|
||||
list.Add( str );
|
||||
}
|
||||
}
|
||||
return (String[])list.ToArray( typeof( String ) );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将字符串写入某个文件中(采用UTF8编码)
|
||||
/// </summary>
|
||||
/// <param name="absolutePath">文件的绝对路径</param>
|
||||
/// <param name="fileContent">需要写入文件的字符串</param>
|
||||
public static void Write( String absolutePath, String fileContent ) {
|
||||
Write( absolutePath, fileContent, Encoding.UTF8 );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将字符串写入某个文件中(需要指定文件编码方式)
|
||||
/// </summary>
|
||||
/// <param name="absolutePath">文件的绝对路径</param>
|
||||
/// <param name="fileContent">需要写入文件的字符串</param>
|
||||
/// <param name="encoding">编码方式</param>
|
||||
public static void Write( String absolutePath, String fileContent, Encoding encoding ) {
|
||||
using (StreamWriter writer = new StreamWriter( absolutePath, false, encoding )) {
|
||||
writer.Write( fileContent );
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除文件
|
||||
/// </summary>
|
||||
/// <param name="absolutePath">文件的绝对路径</param>
|
||||
public static void Delete( String absolutePath ) {
|
||||
System.IO.File.Delete( absolutePath );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 判断文件是否存在
|
||||
/// </summary>
|
||||
/// <param name="absolutePath">文件的绝对路径</param>
|
||||
/// <returns></returns>
|
||||
public static Boolean Exists( String absolutePath ) {
|
||||
return System.IO.File.Exists( absolutePath );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 移动文件
|
||||
/// </summary>
|
||||
/// <param name="sourceFileName">原来的路径</param>
|
||||
/// <param name="destFileName">需要挪到的新路径</param>
|
||||
public static void Move( String sourceFileName, String destFileName ) {
|
||||
System.IO.File.Move( sourceFileName, destFileName );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 拷贝文件(如果目标存在,不覆盖)
|
||||
/// </summary>
|
||||
/// <param name="sourceFileName">原来的路径</param>
|
||||
/// <param name="destFileName">需要挪到的新路径</param>
|
||||
public static void Copy( String sourceFileName, String destFileName ) {
|
||||
System.IO.File.Copy( sourceFileName, destFileName, false );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 拷贝文件
|
||||
/// </summary>
|
||||
/// <param name="sourceFileName">原来的路径</param>
|
||||
/// <param name="destFileName">需要挪到的新路径</param>
|
||||
/// <param name="overwrite">如果目标存在,是否覆盖</param>
|
||||
public static void Copy( String sourceFileName, String destFileName, Boolean overwrite ) {
|
||||
System.IO.File.Copy( sourceFileName, destFileName, overwrite );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将内容追加到文件中(采用UTF8编码)
|
||||
/// </summary>
|
||||
/// <param name="absolutePath">文件的绝对路径</param>
|
||||
/// <param name="fileContent">需要追加的内容</param>
|
||||
public static void Append( String absolutePath, String fileContent ) {
|
||||
Append( absolutePath, fileContent, Encoding.UTF8 );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将内容追加到文件中
|
||||
/// </summary>
|
||||
/// <param name="absolutePath">文件的绝对路径</param>
|
||||
/// <param name="fileContent">需要追加的内容</param>
|
||||
/// <param name="encoding">编码方式</param>
|
||||
public static void Append( String absolutePath, String fileContent, Encoding encoding ) {
|
||||
using (StreamWriter writer = new StreamWriter( absolutePath, true, encoding )) {
|
||||
writer.Write( fileContent );
|
||||
}
|
||||
}
|
||||
|
||||
//public static void Zip( String sourceFileName ) {
|
||||
// Zip( sourceFileName, sourceFileName + ".zip" );
|
||||
//}
|
||||
|
||||
//public static void Zip( String sourceFileName, String destFileName ) {
|
||||
// throw new Exception( "Zip 方法未实现" );
|
||||
//}
|
||||
|
||||
//public static void UnZip( String sourceFileName ) {
|
||||
// throw new Exception( "UnZip 方法未实现" );
|
||||
//}
|
||||
|
||||
//public static void UnZip( String sourceFileName, String destFilePath ) {
|
||||
// throw new Exception( "UnZip 方法未实现" );
|
||||
//}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Web;
|
||||
using Zhaizj.Framework.Web;
|
||||
|
||||
namespace Zhaizj.Framework.IO {
|
||||
|
||||
internal class LinuxPath : PathTool {
|
||||
|
||||
public override String CombineAbs( String[] arrPath ) {
|
||||
|
||||
if (arrPath.Length == 0) return "";
|
||||
|
||||
String result = arrPath[0];
|
||||
for (int i = 1; i < arrPath.Length; i++) {
|
||||
if (strUtil.IsNullOrEmpty( arrPath[i] )) continue;
|
||||
result = strUtil.Join( result, arrPath[i].Replace( "\\", "/" ) );
|
||||
}
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
public override String Map( String path ) {
|
||||
|
||||
if (strUtil.IsNullOrEmpty( path )) return "";
|
||||
|
||||
if (SystemInfo.IsWeb == false) {
|
||||
|
||||
return strUtil.Join( AppDomain.CurrentDomain.BaseDirectory, path );
|
||||
}
|
||||
else {
|
||||
|
||||
String str = path;
|
||||
if (path.ToLower().StartsWith( SystemInfo.ApplicationPath ) == false)
|
||||
str = strUtil.Join( SystemInfo.ApplicationPath, path );
|
||||
|
||||
return HttpContext.Current.Server.MapPath( path );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Zhaizj.Framework.Web;
|
||||
using System.Web;
|
||||
|
||||
namespace Zhaizj.Framework.IO {
|
||||
|
||||
internal abstract class PathTool {
|
||||
|
||||
public abstract String CombineAbs( String[] arrPath );
|
||||
public abstract String Map( String path );
|
||||
|
||||
public static PathTool getInstance() {
|
||||
if (SystemInfo.IsWindows) return new WindowsPath();
|
||||
return new LinuxPath();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// bin 的绝对路径
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static String GetBinDirectory() {
|
||||
if (SystemInfo.IsWeb) {
|
||||
return HttpRuntime.BinDirectory;
|
||||
}
|
||||
|
||||
return AppDomain.CurrentDomain.BaseDirectory;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Web;
|
||||
using Zhaizj.Framework.Web;
|
||||
|
||||
namespace Zhaizj.Framework.IO {
|
||||
|
||||
internal class WindowsPath : PathTool {
|
||||
|
||||
public override String CombineAbs( String[] arrPath ) {
|
||||
|
||||
if (arrPath.Length == 0) return "";
|
||||
|
||||
String result = arrPath[0];
|
||||
for (int i = 1; i < arrPath.Length; i++) {
|
||||
if (strUtil.IsNullOrEmpty( arrPath[i] )) continue;
|
||||
result = strUtil.Join( result, arrPath[i].Replace( "/", "\\" ), "\\" );
|
||||
}
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
public override String Map( String path ) {
|
||||
|
||||
if (strUtil.IsNullOrEmpty( path )) return "";
|
||||
|
||||
if (SystemInfo.IsWeb == false) {
|
||||
|
||||
return strUtil.Join( AppDomain.CurrentDomain.BaseDirectory, path.Replace( "/", "\\" ), "\\" );
|
||||
}
|
||||
else {
|
||||
|
||||
String str = path;
|
||||
if (path.ToLower().StartsWith( SystemInfo.ApplicationPath ) == false)
|
||||
str = strUtil.Join( SystemInfo.ApplicationPath, path );
|
||||
|
||||
return HttpContext.Current.Server.MapPath( str );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
using Zhaizj.Framework.IO;
|
||||
|
||||
namespace Zhaizj.Framework {
|
||||
|
||||
/// <summary>
|
||||
/// 封装了文件常用操作方法
|
||||
/// </summary>
|
||||
public class file : File {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,171 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Zhaizj.Framework.Web;
|
||||
|
||||
namespace Zhaizj.Framework {
|
||||
|
||||
/// <summary>
|
||||
/// 语言包工具,用于加载多国语言。
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 默认语言包文件存放在 /framework/lang/ 中,比如 /framework/lang/zh-cn/ 。只要在 /framework/lang/ 中新增一个语言包文件夹,则系统将其作为语言包列表自动加载。可添加的语言包名称包括:en-us,en-gb,zh-cn,zh-tw,ja,ko,fr,de,it
|
||||
/// </remarks>
|
||||
public class lang {
|
||||
|
||||
// 这个一定要放在第一行,以保证第一个加载
|
||||
private static Dictionary<String, Dictionary<String, LanguageSetting>> langLocaleAll = getLangLocale();
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前语言字符(比如 zh-cn,或 en-us)
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static String getLangString() {
|
||||
|
||||
String defaultLang = "zh-cn";
|
||||
|
||||
String langCookie = CurrentRequest.getLangCookie();
|
||||
if (strUtil.HasText( langCookie ) && langLocaleAll.ContainsKey( langCookie )) return langCookie;
|
||||
|
||||
if (CurrentRequest.getUserLanguages() == null) return defaultLang;
|
||||
String[] reqLangs = CurrentRequest.getUserLanguages();
|
||||
if (reqLangs.Length == 0) return defaultLang;
|
||||
if (langLocaleAll.ContainsKey( reqLangs[0] )) return reqLangs[0];
|
||||
|
||||
return defaultLang;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取某 key 的语言值
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
public static String get( String key ) {
|
||||
try {
|
||||
String langStr = getLangString();
|
||||
return getCoreLang( langStr ).getLangMap() [key];
|
||||
|
||||
}
|
||||
catch (KeyNotFoundException) {
|
||||
throw new KeyNotFoundException( "language's key not found: " + key );
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取在 core.config 中定义的核心语言包
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static LanguageSetting getCoreLang() {
|
||||
return getCoreLang( getLangString() );
|
||||
}
|
||||
|
||||
private static LanguageSetting getCoreLang( String langStr ) {
|
||||
Dictionary<String, LanguageSetting> langlist = langLocaleAll[langStr];
|
||||
return langlist["core"];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据类型 t 获取语言列表
|
||||
/// </summary>
|
||||
/// <param name="t"></param>
|
||||
/// <returns></returns>
|
||||
public static LanguageSetting getByApp( Type t ) {
|
||||
|
||||
Dictionary<String, LanguageSetting> langlist = langLocaleAll[getLangString()];
|
||||
LanguageSetting result;
|
||||
langlist.TryGetValue( t.FullName, out result );
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
private static Dictionary<String, Dictionary<String, LanguageSetting>> getLangLocale() {
|
||||
|
||||
String dirRoot = PathHelper.Map( getLangRootPath() );
|
||||
|
||||
String[] dirPaths = Directory.GetDirectories( dirRoot );
|
||||
|
||||
Dictionary<String, Dictionary<String, LanguageSetting>> results = new Dictionary<String, Dictionary<String, LanguageSetting>>();
|
||||
foreach (String path in dirPaths) {
|
||||
String langName = Path.GetFileName( path );
|
||||
results.Add( langName.ToLower(), getLangList( path ) );
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
private static Dictionary<String, LanguageSetting> getLangList( String path ) {
|
||||
|
||||
String[] files = Directory.GetFiles( path );
|
||||
|
||||
Dictionary<String, LanguageSetting> results = new Dictionary<String, LanguageSetting>();
|
||||
|
||||
foreach (String file in files) {
|
||||
|
||||
if (Path.GetExtension( file ) != ".config") continue;
|
||||
|
||||
String fileName = Path.GetFileNameWithoutExtension( file );
|
||||
|
||||
Dictionary<String, String> _lang = cfgHelper.Read( file, '=' );
|
||||
LanguageSetting lbl = new LanguageSetting( fileName, _lang );
|
||||
|
||||
results.Add( fileName, lbl );
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
private static String getLangRootPath() {
|
||||
return cfgHelper.FrameworkRoot + "lang/";
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// 获取所有支持的语言包
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static List<Dictionary<String, String>> GetSupportedLang() {
|
||||
|
||||
List<Dictionary<String, String>> list = new List<Dictionary<String, String>>();
|
||||
foreach (String key in langLocaleAll.Keys) {
|
||||
Dictionary<String, String> pair = new Dictionary<String, String>();
|
||||
pair.Add( "Name", GetLangInfo( key ) );
|
||||
pair.Add( "Value", key );
|
||||
list.Add( pair );
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private static String GetLangInfo( String langStr ) {
|
||||
if (langMap.ContainsKey( langStr )) return langMap[langStr];
|
||||
return langStr;
|
||||
}
|
||||
|
||||
private static Dictionary<String, String> langMap = getLangInfo();
|
||||
|
||||
private static Dictionary<String, String> getLangInfo() {
|
||||
Dictionary<String, String> map = new Dictionary<String, String>();
|
||||
map.Add( "en-us", "English (US)" );
|
||||
map.Add( "en-gb", "English (British)" );
|
||||
map.Add( "zh-cn", "中文(简体)" ); // skipLang
|
||||
map.Add( "zh-tw", "正體中文(繁體)" ); // skipLang
|
||||
map.Add( "ja", "日本語" );// skipLang
|
||||
map.Add( "ko", "한국어" );
|
||||
map.Add( "fr", "Français" );
|
||||
map.Add( "de", "Deutsch" );
|
||||
map.Add( "it", "Italiano" );
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
|
||||
using System.Web;
|
||||
|
||||
namespace Zhaizj.Framework {
|
||||
|
||||
/// <summary>
|
||||
/// 某个语言包配置文件的内容,包括一个名称和一个语言包的 Dictionary
|
||||
/// </summary>
|
||||
public class LanguageSetting {
|
||||
|
||||
private String name;
|
||||
private Dictionary<String, String> langMap;
|
||||
|
||||
public LanguageSetting( String name, Dictionary<String, String> lang ) {
|
||||
this.name = name;
|
||||
this.langMap = lang;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据 key 获取语言值
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
public String get( String key ) {
|
||||
return langMap[key];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取语言的键值对 Dictionary
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public Dictionary<String, String> getLangMap() {
|
||||
return this.langMap;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
|
||||
using System.Web;
|
||||
|
||||
namespace Zhaizj.Framework {
|
||||
|
||||
/// <summary>
|
||||
/// 获取某个 app 的语言包
|
||||
/// </summary>
|
||||
public class alang {
|
||||
|
||||
/// <summary>
|
||||
/// 根据 app 的类型 t 获取某 key 的语言值
|
||||
/// </summary>
|
||||
/// <param name="t">app 的类型</param>
|
||||
/// <param name="key">语言 key</param>
|
||||
/// <returns></returns>
|
||||
public static String get( Type t, String key ) {
|
||||
LanguageSetting ls = lang.getByApp( t );
|
||||
return ls == null ? null : ls.get( key );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user