找出Framework 4.0 新增的方法和新增的类(下)

简介:

 

为什么动态加载程序集无法找出Framework 4.0 Framwork2.0 新增的方法和类?

 

因为控制台程序默认就添加了Framework4.0的程序集,当你使用ObjectTypestring这些类的时候就已经在使用已经加载的程序集了,clr不会重复的去加载程序集??,这点记不清了。

所以V2Assembly v4Assembly都是Framework4.0Assembly。

验证:

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();
}

输出如下:

image

 

因为mscorlib.dll 是在Share Domain中的程序集,所以在同一应用程序中无法加载两个不同的mscorlib.dll.所以考虑使用两个应用程序,一个Framework 2.0,另一个Framework 4.0。

于是可以换个思路:使用2.0framework来创建的程序来调用framework4.0WCF服务。

代码结构如下:

image

V4NewLooker是基于framework 2.0Winform程序

V4WcfService是基于framework 4.0 WCF服务。

 

接口的定义如下:

namespace V4WcfService
{
    // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码和配置文件中的接口名“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; }
    }
}

 

服务实现代码如下:

namespace V4WcfService
{
    // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码、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();
        }
    }
}

 

服务的实现和第一个反射的版本差不多。

 

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">
          <!-- 为避免泄漏元数据信息,请在部署前将以下值设置为 false 并删除上面的元数据终结点 -->
          <serviceMetadata httpGetEnabled="true"/>
          <!-- 要接收故障异常详细信息以进行调试,请将以下值设置为 true。在部署前设置为 false 以避免泄漏异常信息 -->
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

 

因为默认的maxReceivedMessageSize 65536,所以在后面增加了两个0, 否则会抛出经典的超出范围的异常。

 

 

WinForm程序界面如下:

image

 

后台代码如下:

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;
                }
            }
        }
    }
}

 

搜索按钮的功能就是把当前Framework 2.0的所有的Type,所有的Type中的MemberInfo封装成请求,然后调用WCF服务。服务就会根据传递过来的TypeMemberInfo来输出新增的方法和类。

 

运行效果如下:

image

 

可以看到4.0的File类增加了ReadLines.AppendAllLines方法。上面看到两个ReadLines是因为ReadLines方法由两个重载。






本文转自LoveJenny博客园博客,原文链接:http://www.cnblogs.com/LoveJenny/archive/2011/10/12/2208062.html,如需转载请自行联系原作者
目录
相关文章
|
6月前
|
编译器 C# 开发者
C# 11.0中的新特性:覆盖默认接口方法
C# 11.0进一步增强了接口的灵活性,引入了覆盖默认接口方法的能力。这一新特性允许类在实现接口时,不仅可以提供接口中未实现的方法的具体实现,还可以覆盖接口中定义的默认方法实现。本文将详细介绍C# 11.0中接口默认方法覆盖的工作原理、使用场景及其对现有代码的影响,帮助开发者更好地理解和应用这一新功能。
|
SQL 数据库连接 数据库
使用自定义的类CSetODBC(二)
使用自定义的类CSetODBC(二)
使用自定义的类CSetODBC(一)
使用自定义的类CSetODBC(一)
|
6月前
ES6对象新增了哪些扩展?
ES6对象新增了哪些扩展?
65 0
ES6中对象新增了哪些扩展?
ES6中,当对象键名与对应值名相等的时候,可以进行简写
|
JavaScript 索引
数组的扩展和新增方法
数组的扩展和新增方法
96 0
.NET Core反射获取带有自定义特性的类,通过依赖注入根据Attribute元数据信息调用对应的方法
.NET Core反射获取带有自定义特性的类,通过依赖注入根据Attribute元数据信息调用对应的方法
171 0
|
开发框架 JSON 前端开发
【C#】.net core2.1,自定义全局类对API接口和视图页面产生的异常统一处理
在开发一个网站项目时,异常处理和过滤功能是最基础的模块 本篇文章就来讲讲,如何自定义全局异常类来统一处理
240 0
|
Java
Java中File类概述和构造方法、创建功能、判断和获取功能及删除功能
File类概述和构造方法、创建功能、判断和获取功能及删除功能的简单示例
146 0
Java中File类概述和构造方法、创建功能、判断和获取功能及删除功能