C#反射的实现

一,什么是反射?

1,System.Reflection 命名空间中的类与 System.Type 使你能够获取有关加载的程序集和其中定义的类型的信息,如类、接口和值类型。 可以使用反射在运行时创建、调用和访问类型实例。

2,System.Type 类对于反射起着核心的作用。 当反射请求加载的类型时,公共语言运行时将为它创建一个 Type。 您可以使用 Type 对象的方法、字段、属性和嵌套类来查找有关该类型的所有信息。

3,动态的创建类型的实例,将类型邦定到现有对象,或从现有对象中获取类型 (动态获取程序集)

4,应用程序需要在运行时从某个特定的程序集中载入一个特定的类型,以便实现某个任务时可以用到反射

二,简单工厂的设计

项目各层之间的引用情况:

FanSheLK引用IFanSheLK

DataBLL引用FanSheLK,IFanSheLK和DataDemo

DataDemo引用IFanSheLK

MvcTest引用DataBLL

三,代码如下

FanSheLK代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using IFanSheLK;

namespace FanSheLK
{
    public class Class1 : IClass1
    {
        public void aa()
        {
            Console.WriteLine("aa");
        }
    }
}

IFanSheLK的代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace IFanSheLK
{
    public interface IClass1
    {
        void aa();
    }
}

DataDemo代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using IFanSheLK;
using System.Reflection;

namespace DataDemo
{
    public sealed class DataAccess
    {
        private static readonly string AssemblyPath = "FanSheLK";
        public DataAccess()
        { }

        #region CreateObject

        //不使用缓存
        private static object CreateObjectNoCache(string AssemblyPath, string classNamespace)
        {
            try
            {
                //使用 Assembly 来定义和加载程序集,加载程序集清单中列出的模块,以及在此程序集中定位一个类型并创建一个它的实例。
                object objType = Assembly.Load(AssemblyPath).CreateInstance(classNamespace);
                return objType;
            }
            catch(Exception e)
            {
                return e.Message;
            }

        }
        #endregion

        /// <summary>
        /// 创建数据层接口。
        /// </summary>
        public static IClass1 CreateUser()
        {
            string ClassNamespace = "FanSheLK.Class1";
            object objType = CreateObjectNoCache(AssemblyPath, ClassNamespace);
            return (IClass1)objType;
        }

    }
}

DataBLL的代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DataDemo;
using IFanSheLK;

namespace DataBLL
{
    public class Class1
    {
        public readonly IClass1 a = DataAccess.CreateUser();
        public Class1() {

        }
        public string Test() {
            return "成功";
        }
    }
}

MVC的HomeController.cs的调用实现

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using DataBLL;

namespace MvcTest.Controllers
{
    public class HomeController : Controller
    {
        //
        // GET: /Home/

        public ActionResult Index()
        {
            Class1 a = new Class1();
            a.Test();
            return View();
        }

    }
}

三,然而在实现反射的过程中最容易出现的问题就是:未能加载文件或程序集“xxx(FanSheLK)”或它的某一个依赖项。系统找不到指定的文件。

这是由于反射中的这个造成的Assembly.Load(AssemblyPath).CreateInstance(classNamespace);,切确来说是Assembly.Load(AssemblyPath)这找到不要反射的类库

PS:    到这个时候就要检查下你加载DLL路径是否错误,即DLL文件存在,但加载路径不正确

但是在此之前你要明白:Assembly.Load()要加载的DLL路径究竟是哪里!!!!!!!!!!

根据问题,有以下猜测:

1》在反射方法类库的\bin\Debug下?(即我项目的DataDemo\bin\Debug)

2》在MVC站点的\bin\Debug下?(即我项目的MvcTest\bin\Debug)

3》在反射实现类库的\bin\Debug下?(即我项目的DataBLL\bin\Debug)

解决如下:

1》在反射方法类库(DataDemo),添加要反射类库(FanSheLK)的引用,将生成的FanSheLK.dll到项目的DataDemo\bin\Debug下,但是经过实验证明,这是错误的,一样提示:未能加载文件或程序集“xxx(FanSheLK)”或它的某一个依赖项。系统找不到指定的文件

2》在MVC站点添加引用,添加要反射类库(FanSheLK)的引用,将生成的FanSheLK.dll到项目的\bin\Debug下,神奇的结果出现了,方法Assembly.Load成功加载了,但是还需要继续实验下去。。。。

3》在反射实现类库(DataBLL),添加引用,添加要反射类库(FanSheLK)的引用,将生成的FanSheLK.dll到项目的\bin\Debug下,神奇的结果又出现了,方法Assembly.Load成功加载了

这样又出现新的问题:为什么会有两种假设成功?根据以上两种情况分别引用,我们查看他们的相同的地方和不相同的地方

1》先将反射实现类库(DataBLL)和在MVC站点的项目的\bin\Debug下DLL都删掉

2》在MVC站点添加引用,添加要反射类库(FanSheLK)的引用,项目重新生成,我们会发现FanSheLK.dll会在MVC站点的\bin\Debug下生成,而反射实现类库(DataBLL)并没有

3》在反射实现类库(DataBLL),添加引用,添加要反射类库(FanSheLK)的引用,项目重新生成,在这一次,我们会发现FanSheLK.dll会在MVC站点的\bin\Debug下和反射实现类库(DataBLL)下生成

4》经过以上对比我们发现共同点:FanSheLK.dll会在MVC站点的\bin\Debug下生成,那我们把他删掉,测试

5》得出结论:Assembly.Load()寻找的地址是在MVC站点的\bin\Debug下,则如果反射出现:未能加载文件或程序集“xxx(FanSheLK)”或它的某一个依赖项。系统找不到指定的文件。错误时:我们应该查看该目录下是否存在反射类库的DLL

PS:为什么在反射实现类库(DataBLL),添加引用,添加要反射类库(FanSheLK)的引用,项目重新生成,FanSheLK.dll会在MVC站点的\bin\Debug下和反射实现类库(DataBLL)下同时生成?

原因是我的DataBLL被MVC站点引用,所以会生成DataBLL的引用的DLL,如果是隔着多层类库就不行(如:站点引用A库,A库引用B库,B库引用C库,站点会生成A.DLL和B.DLL而不会生成C.DLL),但是这在类库中并不会(如A库引用B库,A库编译是并不会将B库的引用编译)

时间: 2024-10-07 21:08:18

C#反射的实现的相关文章

Android小例子:使用反射机制来读取图片制作一个图片浏览器

效果图: 工程文件夹: 该例子可供于新手参考练习,如果有哪里不对的地方,望指正>-< <黑幕下的人> java代码(MainActivity.java): package com.example.imageswitchtest; import java.lang.reflect.Field; import android.app.Activity; import android.os.Bundle; import android.util.Log; import android.v

.Net 反射

反射是.NET中的重要机制,通过反射,可以在运行时获得程序或程序集中每一个类型(包括类.结构.委托.接口和枚举等)的成员和成员的信息.有了反射,即可对每一个类型了如指掌.另外我还可以直接创建对象,即使这个对象的类型在编译时还不知道.     反射的用途:    (1)使用Assembly定义和加载程序集,加载在程序集清单中列出模块,以及从此程序集中查找类型并创建该类型的实例.     (2)使用Module了解包含模块的程序集以及模块中的类等,还可以获取在模块上定义的所有全局方法或其他特定的非全

C#图解教程 第二十四章 反射和特性

反射和特性元数据和反射Type 类获取Type对象什么是特性应用特性预定义的保留的特性Obsolete(废弃)特性Conditional特性调用者信息特性DebuggerStepThrough 特性其他预定义特性有关应用特性的更多内容多个特性其他类型的目标全局特性自定义特性声明自定义特性使用特性的构造函数指定构造函数使用构造函数构造函数中的位置参数和命名参数限制特性的使用自定义特性的最佳实践访问特性使用IsDefined方法使用GetCustomAttributes方法 Note 类的元数据包含

Java反射

1. 介绍 反射是一种能够在程序运行时动态访问.修改某个类中任意属性和方法的机制. 具体:对于任意一个类,都能够知道这个类的所有属性和方法对于任意一个对象,都能够调用它的任意一个方法和属性 在运行时,当加载完类之后,JVM在堆内存中会自动产生一个Class类型的对象,这个对象包含了完整的类的结构信息 这个Class对象就像一面镜子,透过这个镜子看到类的结构 那么,如何得到这个Class对象呢?以下可否 Class c = new Class(); 答案是不行的,因为Class的构造函数定义为私有

深入理解Java:类加载机制及反射

一.Java类加载机制 1.概述 Class文件由类装载器装载后,在JVM中将形成一份描述Class结构的元信息对象,通过该元信息对象可以获知Class的结构信息:如构造函数,属性和方法等,Java允许用户借由这个Class相关的元信息对象间接调用Class对象的功能. 虚拟机把描述类的数据从class文件加载到内存,并对数据进行校验,转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制. 2.工作机制 类装载器就是寻找类的字节码文件,并构造出类在JVM内部表示

通过反射了解集合泛型的本质

通过反射了解集合泛型的本质 import java.lang.reflect.Method; import java.util.ArrayList; /** * 通过反射了解集合泛型的本质 * @author shm * */ public class MethodDemo02 { public static void main(String[] args) { ArrayList list = new ArrayList(); list.add("hello"); list.add(

Java 反射详解

反射反射,程序员的快乐,今天你快乐了吗?如果你不快乐,没关系,接下来让你快乐起来! 一.什么是反射? 通过百度百科我们可以知道,Java反射就是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意方法和属性:并且能改变它的属性.而这也是Java被视为动态(或准动态,为啥要说是准动态,因为一般而言的动态语言定义是程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言.从这个观点看,Perl,Python,Ruby是动态语言,C++,Java,C

java中的反射机制和javaBean

反射 反射:就是通过一个类加载进方法区时加载到栈内存中的Class字节码文件对这个类进行解剖 通过反射可以获取到一个类的构造方法,成员方法,成员变量 反射将一个类的各个部分映射成相应的类 反射获取构造方法 Class类中方法 Constructor<?>[] getConstructors() 返回当前字节码文件对象的所有public修饰的构造方法 Constructor<T> getConstructor(Class<?>...parameterTypes)返回指定了

反射机制2,Class类的使用

class是反射源头,不光可以取得对象所在类信息,也可直接通过class类的方法进行对象的实例化操作. 使用关键字new为对象实例化.如果已经实例化好了class对象,就可以通过class类中提供的newInstance()操作 public T newInstance() throws InstantiationException, IllegalAccessException 来个例子: package 类集; class Person{ private String name ; // n

python 反射

1. 反射 实例:伪造web框架中的路由系统 利用反射导入模块 obj = __import__('commons') obj = __import__('lib.' + 'commons',fromlist = True) 导入模块不在当前目录下,需要设置fromlist参数为真, 才能拼接模块路径 利用反射操作对象成员(属性) 通过传入字符串,操作(检查/获取/删除/设置)对象成员(属性) hasattr(对象名,字符串),如果对象中存在名为字符串的属性(成员),返回True,否则返回Fal