YbSoftwareFactory 的 ASP.NET MVC 外掛程式所產生的項目目前支援緩衝、審計日誌和匯出功能。
1、緩衝功能:
緩衝的目的是提高效能,緩衝的設計也有一定的規範性可言,主要需要注意的是緩衝不是完全可靠的,可能會被系統自動移除,同時易變的資料也不適合緩衝。因此考慮到具體的情境,僅對審計日誌、資料字典等不經常變化的資料進行了緩衝,同時,即使這些資料被修改或刪除也要及時把對應的緩衝內容清除,以確保資料的準確。
緩衝的實現借鑒了NopCommerce的實現方式,採用擴充方法加回呼函數的做法,這樣在任何需要緩衝的地方都能進行緩衝的處理,擴充方法的核心代碼如下:
/// <summary>
/// Extensions
/// </summary>
public static class CacheExtensions
{
public static T Get<T>(this ICacheManager cacheManager, string key, Func<T> acquire)
{
return Get(cacheManager, key, 60, acquire);
}
public static T Get<T>(this ICacheManager cacheManager, string key, int cacheTime, Func<T> acquire)
{
if (cacheManager.IsSet(key))
{
return cacheManager.Get<T>(key);
}
else
{
var result = acquire();
//if (result != null)
cacheManager.Set(key, result, cacheTime);
return result;
}
}
}
具體的緩衝調用可以這樣,是不是很靈活:-)
string key = string.Format(CacheKeyList.CONCRETEDATA_BY_TYPE_KEY, concreteType);
var items = _cacheManager.Get(key, () =>
{
var list = ConcreteDataApi.FindAllByType(concreteType).Where(c => c.Status == 0);
return list;
});
2、審計日誌功能:
審計的概念涉及到系統安全,資料審計的目的之一是解決“授權侵犯”的問題(特指已授權使用者執行非法操作的情況)。本系統的審計日誌功能和log4net相相容,可以通過配置log4net組件進行日誌記錄的讀寫,同時增強資料審計功能還可自動記錄業務資料添加、修改、刪除的詳細變化情況,是不是很強大:-)
3、資料匯出功能:
在ASP.NET MVC下資料匯出比較簡單,但本系統需實現的是在 web api下實現資料的匯出和下載,目前這方面的資料較少。經過測試,目前下面的代碼可行,感興趣的朋友可以測試和瞭解一下,有了資料匯出功能是不是很方便:-)
1 public static HttpResponseMessage Download(Stream stream,string headerValue, string fileName)
2 {
3 var response = new HttpResponseMessage { Content = new StreamContent(stream) };
4 response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
5 {
6 FileName = fileName
7 };
8 response.Content.Headers.ContentType = new MediaTypeHeaderValue(headerValue);
9 response.Content.Headers.ContentLength = stream.Length;
10 return response;
11 }
4、資料字典等資料訪問層的實現:
資料字典、審計日誌等功能需要支援多種資料庫環境,同時還要方便部署,這裡通過Provider模式實現,其中連接字串可以在設定檔中用標準方法進行配置,也能在程式中設定、並自訂加減密,而這無需在任何業務系統中編寫代碼,只需配置好資料庫相關表就能進行調用,很是方便,如下是Provider的初始化代碼:
#region Initialize
public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
{
// Validate arguments
if (config == null) throw new ArgumentNullException("config");
if (string.IsNullOrEmpty(name)) name = "YbHierarchyDataProvider";
if (String.IsNullOrEmpty(config["description"]))
{
config.Remove("description");
config.Add("description", "Yb hierarchy data provider");
}
if (String.IsNullOrEmpty(config["tableName"]))
{
config.Remove("tableName");
config.Add("tableName", "HierarchyData");
}
// Initialize base class
base.Initialize(name, config);
// Read connection string
this.ConnectionStringName = config.GetConfigValue("connectionStringName", null);
if (string.IsNullOrWhiteSpace(this.ConnectionStringName)) throw new ConfigurationErrorsException(Resources.Required_connectionStringName_attribute_not_specified);
this.connectionStringSetting = ConfigurationManager.ConnectionStrings[this.ConnectionStringName];
if (this.connectionStringSetting == null) throw new ConfigurationErrorsException(string.Format(Resources.Format_connection_string_was_not_found, this.ConnectionStringName));
if (string.IsNullOrEmpty(this.connectionStringSetting.ProviderName)) throw new ConfigurationErrorsException(string.Format(Resources.Format_connection_string_does_not_have_specified_the_providerName_attribute, this.ConnectionStringName));
//激發設定連接字串前的事件處理常式,主要目的是解密連接字串
ConnectionStringChangingEventArgs args = RaiseConnectionStringChangingEvent(connectionStringSetting.ConnectionString);
if (args == null) throw new ProviderException(Resources.Connection_string_cannot_be_blank);
if (!this.connectionStringSetting.ConnectionString.Equals(args.ConnectionString))
{
this.connectionStringSetting =
new ConnectionStringSettings(this.ConnectionStringName, args.ConnectionString, this.connectionStringSetting.ProviderName);
}
if (string.IsNullOrEmpty(this.connectionStringSetting.ConnectionString)) throw new ProviderException(Resources.Connection_string_cannot_be_blank);
this.applicationName = config["applicationName"];
this.tableName = config["tableName"];
SecUtility.CheckParameter(ref tableName, true, true, true, 256, "tableName");
}
#endregion
要相容各類資料庫,需要注意的是建立串連時需使用DbConnection而不是SqlConnection,需使用DbCommand而不是SqlCommand等,如下是建立資料庫連接的代碼,是不是很規範:-)
using (DbConnection db = this.connectionStringSetting.CreateDbConnection())
最後附上Demo地址:http://mvcdemo.yellbuy.com/。
註:目前的版本V1.1,已有V1.0版本及源碼並需要升級的請及時聯絡。