在Framework 4.0中:找出新增的方法與新增的類(二)
為什么動(dòng)態(tài)加載程序集無(wú)法找出Framework 4.0 和Framwork2.0 新增的方法和類?
因?yàn)榭刂婆_(tái)程序默認(rèn)就添加了Framework4.0的程序集,當(dāng)你使用Object,Type,string這些類的時(shí)候就已經(jīng)在使用已經(jīng)加載的程序集了,而clr不會(huì)重復(fù)的去加載程序集??,這點(diǎn)記不清了。
所以V2Assembly 和v4Assembly都是Framework4.0的Assembly。
驗(yàn)證:
static void Main(string[] args)
{
Assembly assemblyV2 = Assembly.LoadFile(
@"C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\mscorlib.dll");
Assembly assemblyV4 = Assembly.LoadFile(
@"C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\mscorlib.dll");
Console.WriteLine("V2的名稱{0}\nV4的名稱{1}", assemblyV2.FullName, assemblyV4.FullName);
Console.ReadLine();
}
輸出如下:
因?yàn)閙scorlib.dll 是在Share Domain中的程序集,所以在同一應(yīng)用程序中無(wú)法加載兩個(gè)不同的mscorlib.dll.所以考慮使用兩個(gè)應(yīng)用程序,一個(gè)Framework 2.0,另一個(gè)Framework 4.0。
于是可以換個(gè)思路:使用2.0的framework來(lái)創(chuàng)建的程序來(lái)調(diào)用framework4.0的WCF服務(wù)。
代碼結(jié)構(gòu)如下:
V4NewLooker是基于framework 2.0的Winform程序
V4WcfService是基于framework 4.0 的WCF服務(wù)。
接口的定義如下:
namespace V4WcfService
{
// 注意: 使用“重構(gòu)”菜單上的“重命名”命令,可以同時(shí)更改代碼和配置文件中的接口名“IService1”。
[ServiceContract]
public interface IService1
{
[OperationContract]
List<TypeMembers> GetNewTypeMember(List<TypeMembers> lstOldTypes);
}
[DataContract]
public class TypeMembers
{
[DataMember]
public string FullName { get; set; }
[DataMember]
public List<string> MemberNames { get; set; }
}
}
服務(wù)實(shí)現(xiàn)代碼如下:
namespace V4WcfService
{
// 注意: 使用“重構(gòu)”菜單上的“重命名”命令,可以同時(shí)更改代碼、svc 和配置文件中的類名“Service1”。
public class Service1 : IService1
{
public List<TypeMembers> GetNewTypeMember(List<TypeMembers> lstOldTypes)
{
List<TypeMembers> result = new List<TypeMembers>();
Assembly mscorlibAssembly = typeof(object).Assembly;
Type[] v4Types = mscorlibAssembly.GetTypes();
#region 所有更新的Type
foreach (TypeMembers v3Type in lstOldTypes)
{
Type v4Type = v4Types.FirstOrDefault(t => t.FullName == v3Type.FullName);
if (v4Type != null && !v4Type.IsEnum)
{
MemberInfo[] v4Mis = v4Type.GetMembers();
if (v4Mis.Length != v3Type.MemberNames.Count)
{
MemberInfo[] v4NewMis = v4Mis.Where(mi =>
!v3Type.MemberNames.Contains(mi.Name)).ToArray();
result.Add(new TypeMembers()
{
FullName = v4Type.FullName,
MemberNames = v4NewMis.Select(mi => mi.Name).ToList()
});
}
}
}
#endregion
#region 所有新增的Type
List<string> v3TypeFullName = lstOldTypes.Select(tm => tm.FullName).ToList();
Type[] v4NewTypes = v4Types.Where(t => !v3TypeFullName.Contains(t.FullName) &&
!t.IsEnum).ToArray();
foreach (Type v4NewType in v4NewTypes)
{
result.Add(new TypeMembers()
{
FullName = v4NewType.FullName,
MemberNames = v4NewType.GetMembers().Select(mi => mi.Name).ToList()
});
}
#endregion
return result.OrderBy(tm=>tm.FullName).ToList();
}
}
}
服務(wù)的實(shí)現(xiàn)和第一個(gè)反射的版本差不多。
Web.config文件綁定代碼如下:
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="NewBinding0" maxReceivedMessageSize="65536000" />
</wsHttpBinding>
<mexHttpBinding>
<binding name="NewBinding1" />
</mexHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="V4WcfService.Service1Behavior"
name="V4WcfService.Service1">
<endpoint address="" binding="wsHttpBinding" bindingConfiguration="NewBinding0"
contract="V4WcfService.IService1">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" bindingConfiguration="NewBinding1"
contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="V4WcfService.Service1Behavior">
<!-- 為避免泄漏元數(shù)據(jù)信息,請(qǐng)?jiān)诓渴鹎皩⒁韵轮翟O(shè)置為 false 并刪除上面的元數(shù)據(jù)終結(jié)點(diǎn) -->
<serviceMetadata httpGetEnabled="true"/>
<!-- 要接收故障異常詳細(xì)信息以進(jìn)行調(diào)試,請(qǐng)將以下值設(shè)置為 true。在部署前設(shè)置為 false 以避免泄漏異常信息 -->
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
因?yàn)槟J(rèn)的maxReceivedMessageSize 為65536,所以在后面增加了兩個(gè)0, 否則會(huì)拋出經(jīng)典的超出范圍的異常。
WinForm程序界面如下:
后臺(tái)代碼如下:
namespace V4NewLooker
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private List<TypeMembers> NewTypeMembers { get; set; }
private void btnSearch_Click(object sender, EventArgs e)
{
Assembly mscorlibAssembly = typeof(object).Assembly;
List<TypeMembers> v3TypeMembers = new List<TypeMembers>();
foreach (Type v4NewType in mscorlibAssembly.GetTypes())
{
List<string> memberNames = new List<string>();
MemberInfo[] mis = v4NewType.GetMembers();
foreach (MemberInfo mi in mis)
{
memberNames.Add(mi.Name);
}
v3TypeMembers.Add(new TypeMembers()
{
FullName = v4NewType.FullName,
MemberNames = memberNames
});
}
using (Service1Client client = new Service1Client())
{
NewTypeMembers = client.GetNewTypeMember(v3TypeMembers);
}
List<string> typeNames=new List<string>();
foreach (TypeMembers tm in NewTypeMembers)
{
typeNames.Add(tm.FullName);
}
lstBox_Types.DataSource = typeNames;
}
private void lstBox_Types_SelectedIndexChanged(object sender, EventArgs e)
{
string fullName = lstBox_Types.SelectedItem.ToString();
foreach (TypeMembers tm in NewTypeMembers)
{
if (tm.FullName == fullName)
{
lstBox_Members.DataSource = tm.MemberNames;
break;
}
}
}
}
}
搜索按鈕的功能就是把當(dāng)前Framework 2.0的所有的Type,所有的Type中的MemberInfo封裝成請(qǐng)求,然后調(diào)用WCF服務(wù)。服務(wù)就會(huì)根據(jù)傳遞過(guò)來(lái)的Type和MemberInfo來(lái)輸出新增的方法和類。
運(yùn)行效果如下:
可以看到4.0的File類增加了ReadLines.AppendAllLines方法。上面看到兩個(gè)ReadLines是因?yàn)镽eadLines方法由兩個(gè)重載。
相關(guān)文章
C#中StringBuilder用法以及和String的區(qū)別分析
當(dāng)我們?cè)诔鯇W(xué)使用C#時(shí),常常會(huì)不知道該用StringBuilder合適還是用String高效,下面是我在學(xué)習(xí)當(dāng)中對(duì)StringBuilder和String的區(qū)別總結(jié),分享給大家。2013-03-03解決C# winForm自定義鼠標(biāo)樣式的兩種實(shí)現(xiàn)方法詳解
本篇文章是對(duì)在C#中winForm自定義鼠標(biāo)樣式的兩種實(shí)現(xiàn)方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05c# 獲得當(dāng)前絕對(duì)路徑的方法(超簡(jiǎn)單)
下面小編就為大家分享一篇c# 獲得當(dāng)前絕對(duì)路徑的方法(超簡(jiǎn)單),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-01-01C#連接Mysql數(shù)據(jù)庫(kù)詳細(xì)教程(內(nèi)附Mysql及Navicat)
這篇文章主要給大家介紹了C#連接Mysql數(shù)據(jù)庫(kù)詳細(xì)教程(內(nèi)附Mysql及Navicat),文中通過(guò)代碼示例和圖文介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下2023-10-10C#中實(shí)現(xiàn)在32位、64位系統(tǒng)下自動(dòng)切換不同的SQLite dll文件
這篇文章主要介紹了C#中實(shí)現(xiàn)在32位、64位系統(tǒng)下自動(dòng)切換不同的SQLite dll文件,本文使用C#代碼實(shí)現(xiàn)DLL文件的切換,需要的朋友可以參考下2014-09-09C#把數(shù)組中的某個(gè)元素取出來(lái)放到第一個(gè)位置的實(shí)現(xiàn)方法
這篇文章主要介紹了C#把數(shù)組中的某個(gè)元素取出來(lái)放到第一個(gè)位置的實(shí)現(xiàn)方法,涉及C#針對(duì)數(shù)組的常見(jiàn)操作技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2014-12-12