使用C#的反射機制時遇到的問題
阿新 • • 發佈:2019-01-03
專案DALFactory是採用工廠模式設計的,設計模式的書我也曾看過Java的設計模式,理解也不太深刻,但對工廠模式還是較為熟悉,使用它可以根據需求返回不同的例項物件,在DALFactory專案中使用反射機制來實現依賴注入,當然,它的實現還是沒有java中的spring那樣靈活,強大,部分程式碼如下:
// <summary>
/// 抽象工廠模式建立DAL。
/// Web.config 需要加入配置:(利用工廠模式+反射機制+快取機制,實現動態建立不同的資料層物件介面)
/// DataCache類在匯出程式碼的資料夾裡
/// 可以把所有DAL類的建立放在這個DataAccess類裡
/// <appSettings>
/// <add key="DAL" value="SmsSystem.SQLServerDAL" /> (這裡的名稱空間根據實際情況更改為自己專案的名稱空間)
/// </appSettings>
/// </summary>
public sealed class DataAccess
{
private static readonly string path = ConfigurationManager.AppSettings["DAL"];
/// <summary>
/// 建立物件或從快取獲取
/// </summary>
public static object CreateObject(string path, string CacheKey)
{
object objType = DataCache.GetCache(CacheKey);//從快取讀取
if (objType == null)
{
try
{
//Assembly ass = new Assembly();
objType = Assembly.Load(path).CreateInstance(CacheKey);//反射建立
DataCache.SetCache(CacheKey, objType);// 寫入快取
}
catch(System.Exception ex)
{
string str = ex.Message;//
SmsSystem.Utility.SaveLog.SaveInfoToLog(str, "errorLog", "異常");
}
}
return objType;
}
/// <summary>
/// 不使用快取,建立物件
/// </summary>
private static object CreateObjectNoCache(string path, string CacheKey)
{
try
{
object objType = Assembly.Load(path).CreateInstance(CacheKey);
return objType;
}
catch//(System.Exception ex)
{
//string str=ex.Message;// 記錄錯誤日誌
return null;
}
}
/// <summary>
/// 建立CustEmployee資料層介面
/// </summary>
public static SmsSystem.IDAL.ICustEmployee CreateCustEmployee()
{
string CacheKey = path + ".CustEmployee";
object objType = CreateObject(path, CacheKey);
return (ICustEmployee)objType;
}
………………(其它資料層介面)
}
由這一個類,就可以獲取需要用的資料訪問層的例項,可是,我在使用過程中卻總是丟擲異常,[System.IO.FileNotFoundException] = {"未能載入檔案或程式集“SmsSystem.SQLServerDAL”或它的某一個依賴項。系統找不到指定的檔案。":"SmsSystem.SQLServerDAL"} ,說實話,對於C#這排錯和除錯我還手生,我百思不得其解,為什麼會一用反射就異常呢,整個上去我去看反射的IPA,感覺我的用法沒錯誤啊,況且,我看PetShop的例子就是這樣差不多的寫法,它為什麼能用,下午除錯了好久還是在出錯,我發狠心去和petShop去對比,後來終於發現,它的dll的名字有些怪,和我的不同,它的都是如PetShop.SQLServerDAL.dll這樣的名字,而我的就是個SQLServerDAL.dll,我感覺極有可能是這裡有問題,因為在wb.config裡我配置過
<appSettings>
<add key="DAL" value="SmsSystem.SQLServerDAL"/>
…………
</appSettings>
這樣一個程式集,搞了好久,請教別人,結果弄清楚,是要專案的屬性裡設定程式集的名稱,就可以生成SmsSystem.SQLServerDAL.dll這樣的dll檔案
設定,重新生成 ,又出了一點問題,
型別“SmsSystem.BLL.CustEmployee”同時存在於“c:/Windows/Microsoft.net/Framework/v2.0.50727/Temporary ASP.NET Files
/smssystem/3358d7f2/16ba9bb7/assembly/dl3/7296d5df/40ded961_96d8c601/BLL.DLL”
和“c:/WINDOWS/Microsoft.NET/Framework/v2.0.50727/Temporary ASP.NET Files/smssystem/3358d7f2
/16ba9bb7/assembly/dl3/644d894c/4cf8840a_9ad8c601/SmsSystem.BLL.DLL”
中 G:/ASP.NET/SmsSystem/Default.aspx.cs 22
我仔細一看,原來在web專案的bin下面,原來的SQLServerDAL.dll還在,又多了個SmsSystem.SQLServerDAL.dll,哈哈,vs2005又一個沒有自動刪除掉的多餘檔案,昨天是一個專案檔案AssemblyInfo.cs刪除掉後,在相應的刪除檔案竟然沒刪除,不過,我把它手工刪除掉,OK,一切正常,還是感謝告訴我怎麼樣改專案的Assembly name的朋友,不然我竟然找好久也不曉得怎麼生成帶上名稱空間的dll。
// <summary>
/// 抽象工廠模式建立DAL。
/// Web.config 需要加入配置:(利用工廠模式+反射機制+快取機制,實現動態建立不同的資料層物件介面)
/// DataCache類在匯出程式碼的資料夾裡
/// 可以把所有DAL類的建立放在這個DataAccess類裡
/// <appSettings>
/// <add key="DAL" value="SmsSystem.SQLServerDAL" /> (這裡的名稱空間根據實際情況更改為自己專案的名稱空間)
/// </appSettings>
/// </summary>
public sealed class DataAccess
{
private static readonly string path = ConfigurationManager.AppSettings["DAL"];
/// <summary>
/// 建立物件或從快取獲取
/// </summary>
public static object CreateObject(string path, string CacheKey)
{
object objType = DataCache.GetCache(CacheKey);//從快取讀取
if (objType == null)
{
try
{
//Assembly ass = new Assembly();
objType = Assembly.Load(path).CreateInstance(CacheKey);//反射建立
DataCache.SetCache(CacheKey, objType);// 寫入快取
}
catch(System.Exception ex)
{
string str = ex.Message;//
SmsSystem.Utility.SaveLog.SaveInfoToLog(str, "errorLog", "異常");
}
}
return objType;
}
/// <summary>
/// 不使用快取,建立物件
/// </summary>
private static object CreateObjectNoCache(string path, string CacheKey)
{
try
{
object objType = Assembly.Load(path).CreateInstance(CacheKey);
return objType;
}
catch//(System.Exception ex)
{
//string str=ex.Message;// 記錄錯誤日誌
return null;
}
}
/// <summary>
/// 建立CustEmployee資料層介面
/// </summary>
public static SmsSystem.IDAL.ICustEmployee CreateCustEmployee()
{
string CacheKey = path + ".CustEmployee";
object objType = CreateObject(path, CacheKey);
return (ICustEmployee)objType;
}
………………(其它資料層介面)
}
由這一個類,就可以獲取需要用的資料訪問層的例項,可是,我在使用過程中卻總是丟擲異常,[System.IO.FileNotFoundException] = {"未能載入檔案或程式集“SmsSystem.SQLServerDAL”或它的某一個依賴項。系統找不到指定的檔案。":"SmsSystem.SQLServerDAL"} ,說實話,對於C#這排錯和除錯我還手生,我百思不得其解,為什麼會一用反射就異常呢,整個上去我去看反射的IPA,感覺我的用法沒錯誤啊,況且,我看PetShop的例子就是這樣差不多的寫法,它為什麼能用,下午除錯了好久還是在出錯,我發狠心去和petShop去對比,後來終於發現,它的dll的名字有些怪,和我的不同,它的都是如PetShop.SQLServerDAL.dll這樣的名字,而我的就是個SQLServerDAL.dll,我感覺極有可能是這裡有問題,因為在wb.config裡我配置過
<appSettings>
<add key="DAL" value="SmsSystem.SQLServerDAL"/>
…………
</appSettings>
這樣一個程式集,搞了好久,請教別人,結果弄清楚,是要專案的屬性裡設定程式集的名稱,就可以生成SmsSystem.SQLServerDAL.dll這樣的dll檔案
設定,重新生成 ,又出了一點問題,
型別“SmsSystem.BLL.CustEmployee”同時存在於“c:/Windows/Microsoft.net/Framework/v2.0.50727/Temporary ASP.NET Files
/smssystem/3358d7f2/16ba9bb7/assembly/dl3/7296d5df/40ded961_96d8c601/BLL.DLL”
和“c:/WINDOWS/Microsoft.NET/Framework/v2.0.50727/Temporary ASP.NET Files/smssystem/3358d7f2
/16ba9bb7/assembly/dl3/644d894c/4cf8840a_9ad8c601/SmsSystem.BLL.DLL”
中 G:/ASP.NET/SmsSystem/Default.aspx.cs 22
我仔細一看,原來在web專案的bin下面,原來的SQLServerDAL.dll還在,又多了個SmsSystem.SQLServerDAL.dll,哈哈,vs2005又一個沒有自動刪除掉的多餘檔案,昨天是一個專案檔案AssemblyInfo.cs刪除掉後,在相應的刪除檔案竟然沒刪除,不過,我把它手工刪除掉,OK,一切正常,還是感謝告訴我怎麼樣改專案的Assembly name的朋友,不然我竟然找好久也不曉得怎麼生成帶上名稱空間的dll。